GBA Memory: Simplify memory API and use fixed bus width

This commit is contained in:
Jeffrey Pfau 2015-01-10 01:18:11 -08:00
parent f0f929665e
commit 6d18b9aea5
12 changed files with 60 additions and 76 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.loadU8(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.loadU16(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, &currentCycles); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, &currentCycles)); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = ARM_SXT_16(cpu->memory.load16(cpu, address, &currentCycles)); ARM_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory.store32(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory.store8(cpu, address, cpu->gprs[rd], &currentCycles); ARM_STORE_POST_BODY;)
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory.store16(cpu, address, cpu->gprs[rd], &currentCycles); 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, &currentCycles);
cpu->gprs[rd] = cpu->memory.load8(cpu, address, &currentCycles);
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], &currentCycles);
int32_t d = cpu->memory.load8(cpu, cpu->gprs[rn], &currentCycles);
cpu->memory.store8(cpu, cpu->gprs[rn], cpu->gprs[rm], &currentCycles);
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);)

View File

@ -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)))

View File

@ -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, &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRB1, cpu->gprs[rd] = cpu->memory.loadU8(cpu, cpu->gprs[rm] + immediate, &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRH1, cpu->gprs[rd] = cpu->memory.loadU16(cpu, cpu->gprs[rm] + immediate * 2, &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRB1, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rm] + immediate, &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRH1, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rm] + immediate * 2, &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STR1, cpu->memory.store32(cpu, cpu->gprs[rm] + immediate * 4, cpu->gprs[rd], &currentCycles); THUMB_STORE_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STRB1, cpu->memory.store8(cpu, cpu->gprs[rm] + immediate, cpu->gprs[rd], &currentCycles); THUMB_STORE_POST_BODY;)
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STRH1, cpu->memory.store16(cpu, cpu->gprs[rm] + immediate * 2, cpu->gprs[rd], &currentCycles); 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], &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, cpu->gprs[rd] = cpu->memory.loadU8(cpu, cpu->gprs[rn] + cpu->gprs[rm], &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, cpu->gprs[rd] = cpu->memory.loadU16(cpu, cpu->gprs[rn] + cpu->gprs[rm], &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rn] + cpu->gprs[rm], &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rn] + cpu->gprs[rm], &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rn] + cpu->gprs[rm], &currentCycles); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rn] + cpu->gprs[rm], &currentCycles); 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], &currentCycles)); 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], &currentCycles)); THUMB_LOAD_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, cpu->memory.store32(cpu, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], &currentCycles); THUMB_STORE_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRB2, cpu->memory.store8(cpu, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], &currentCycles); THUMB_STORE_POST_BODY;)
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, cpu->memory.store16(cpu, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], &currentCycles); THUMB_STORE_POST_BODY;)

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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);