mirror of https://github.com/mgba-emu/mgba.git
Remove ARMMemory and ARMBoard shims
This commit is contained in:
parent
775e417cc6
commit
c0eb7c81f7
|
@ -36,7 +36,7 @@ if(BUILD_BBB OR BUILD_RASPI)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
set(DEBUGGER_SRC "${CMAKE_SOURCE_DIR}/src/debugger/debugger.c;${CMAKE_SOURCE_DIR}/src/debugger/memory-debugger.c")
|
||||
set(DEBUGGER_SRC "${CMAKE_SOURCE_DIR}/src/debugger/debugger.c")
|
||||
|
||||
if(USE_CLI_DEBUGGER)
|
||||
set(DEBUGGER_SRC "${DEBUGGER_SRC};${CMAKE_SOURCE_DIR}/src/debugger/cli-debugger.c")
|
||||
|
|
|
@ -65,17 +65,7 @@ static inline enum RegisterBank _ARMSelectBank(enum PrivilegeMode mode) {
|
|||
}
|
||||
|
||||
void ARMInit(struct ARMCore* cpu) {
|
||||
cpu->memory = 0;
|
||||
cpu->board = 0;
|
||||
}
|
||||
|
||||
void ARMAssociateMemory(struct ARMCore* cpu, struct ARMMemory* memory) {
|
||||
cpu->memory = memory;
|
||||
}
|
||||
|
||||
void ARMAssociateBoard(struct ARMCore* cpu, struct ARMBoard* board) {
|
||||
cpu->board = board;
|
||||
board->cpu = cpu;
|
||||
// TODO: Remove
|
||||
}
|
||||
|
||||
void ARMReset(struct ARMCore* cpu) {
|
||||
|
@ -111,7 +101,7 @@ void ARMReset(struct ARMCore* cpu) {
|
|||
cpu->cycles = 0;
|
||||
cpu->nextEvent = 0;
|
||||
|
||||
cpu->board->reset(cpu->board);
|
||||
cpu->board.reset(cpu);
|
||||
}
|
||||
|
||||
void ARMRaiseIRQ(struct ARMCore* cpu) {
|
||||
|
@ -129,7 +119,7 @@ void ARMRaiseIRQ(struct ARMCore* cpu) {
|
|||
cpu->cpsr.priv = MODE_IRQ;
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM;
|
||||
cpu->gprs[ARM_PC] = BASE_IRQ + WORD_SIZE_ARM;
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]);
|
||||
cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]);
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
|
@ -147,7 +137,7 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
|
|||
cpu->cpsr.priv = MODE_SUPERVISOR;
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
|
||||
cpu->gprs[ARM_PC] = BASE_SWI + WORD_SIZE_ARM;
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]);
|
||||
cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]);
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
|
@ -156,7 +146,7 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
|
|||
static inline void ARMStep(struct ARMCore* cpu) {
|
||||
uint32_t opcode;
|
||||
cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_ARM;
|
||||
LOAD_32(opcode, cpu->currentPC & cpu->memory->activeMask, cpu->memory->activeRegion);
|
||||
LOAD_32(opcode, cpu->currentPC & cpu->memory.activeMask, cpu->memory.activeRegion);
|
||||
cpu->gprs[ARM_PC] += WORD_SIZE_ARM;
|
||||
|
||||
int condition = opcode >> 28;
|
||||
|
@ -262,7 +252,7 @@ static inline void ThumbStep(struct ARMCore* cpu) {
|
|||
cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_THUMB;
|
||||
cpu->gprs[ARM_PC] += WORD_SIZE_THUMB;
|
||||
uint16_t opcode;
|
||||
LOAD_16(opcode, cpu->currentPC & cpu->memory->activeMask, cpu->memory->activeRegion);
|
||||
LOAD_16(opcode, cpu->currentPC & cpu->memory.activeMask, cpu->memory.activeRegion);
|
||||
ThumbInstruction instruction = _thumbTable[opcode >> 6];
|
||||
instruction(cpu, opcode);
|
||||
}
|
||||
|
@ -274,6 +264,6 @@ void ARMRun(struct ARMCore* cpu) {
|
|||
ARMStep(cpu);
|
||||
}
|
||||
if (cpu->cycles >= cpu->nextEvent) {
|
||||
cpu->board->processEvents(cpu->board);
|
||||
cpu->board.processEvents(cpu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,15 +79,15 @@ union PSR {
|
|||
};
|
||||
|
||||
struct ARMMemory {
|
||||
int32_t (*load32)(struct ARMMemory*, uint32_t address, int* cycleCounter);
|
||||
int16_t (*load16)(struct ARMMemory*, uint32_t address, int* cycleCounter);
|
||||
uint16_t (*loadU16)(struct ARMMemory*, uint32_t address, int* cycleCounter);
|
||||
int8_t (*load8)(struct ARMMemory*, uint32_t address, int* cycleCounter);
|
||||
uint8_t (*loadU8)(struct ARMMemory*, uint32_t address, int* cycleCounter);
|
||||
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);
|
||||
|
||||
void (*store32)(struct ARMMemory*, uint32_t address, int32_t value, int* cycleCounter);
|
||||
void (*store16)(struct ARMMemory*, uint32_t address, int16_t value, int* cycleCounter);
|
||||
void (*store8)(struct ARMMemory*, uint32_t address, int8_t value, 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);
|
||||
void (*store8)(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
|
||||
|
||||
uint32_t* activeRegion;
|
||||
uint32_t activeMask;
|
||||
|
@ -95,20 +95,19 @@ struct ARMMemory {
|
|||
uint32_t activePrefetchCycles16;
|
||||
uint32_t activeNonseqCycles32;
|
||||
uint32_t activeNonseqCycles16;
|
||||
void (*setActiveRegion)(struct ARMMemory*, uint32_t address);
|
||||
int (*waitMultiple)(struct ARMMemory*, uint32_t startAddress, int count);
|
||||
void (*setActiveRegion)(struct ARMCore*, uint32_t address);
|
||||
int (*waitMultiple)(struct ARMCore*, uint32_t startAddress, int count);
|
||||
};
|
||||
|
||||
struct ARMBoard {
|
||||
struct ARMCore* cpu;
|
||||
void (*reset)(struct ARMBoard* board);
|
||||
void (*processEvents)(struct ARMBoard* board);
|
||||
void (*swi16)(struct ARMBoard* board, int immediate);
|
||||
void (*swi32)(struct ARMBoard* board, int immediate);
|
||||
void (*hitIllegal)(struct ARMBoard* board, uint32_t opcode);
|
||||
void (*readCPSR)(struct ARMBoard* board);
|
||||
void (*reset)(struct ARMCore* board);
|
||||
void (*processEvents)(struct ARMCore* board);
|
||||
void (*swi16)(struct ARMCore* board, int immediate);
|
||||
void (*swi32)(struct ARMCore* board, int immediate);
|
||||
void (*hitIllegal)(struct ARMCore* board, uint32_t opcode);
|
||||
void (*readCPSR)(struct ARMCore* board);
|
||||
|
||||
void (*hitStub)(struct ARMBoard* board, uint32_t opcode);
|
||||
void (*hitStub)(struct ARMCore* board, uint32_t opcode);
|
||||
};
|
||||
|
||||
struct ARMCore {
|
||||
|
@ -130,8 +129,8 @@ struct ARMCore {
|
|||
enum ExecutionMode executionMode;
|
||||
enum PrivilegeMode privilegeMode;
|
||||
|
||||
struct ARMMemory* memory;
|
||||
struct ARMBoard* board;
|
||||
struct ARMMemory memory;
|
||||
struct ARMBoard board;
|
||||
|
||||
int64_t absoluteCycles;
|
||||
int32_t lastCycles;
|
||||
|
|
|
@ -249,7 +249,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
|
||||
#define ARM_STORE_POST_BODY \
|
||||
currentCycles -= ARM_PREFETCH_CYCLES; \
|
||||
currentCycles += 1 + cpu->memory->activeNonseqCycles32;
|
||||
currentCycles += 1 + cpu->memory.activeNonseqCycles32;
|
||||
|
||||
#define DEFINE_INSTRUCTION_ARM(NAME, BODY) \
|
||||
static void _ARMInstruction ## NAME (struct ARMCore* cpu, uint32_t opcode) { \
|
||||
|
@ -424,7 +424,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
S_PRE; \
|
||||
LOOP(BODY); \
|
||||
S_POST; \
|
||||
currentCycles += cpu->memory->waitMultiple(cpu->memory, addr, total); \
|
||||
currentCycles += cpu->memory.waitMultiple(cpu, addr, total); \
|
||||
POST_BODY; \
|
||||
WRITEBACK;)
|
||||
|
||||
|
@ -543,68 +543,68 @@ DEFINE_MULTIPLY_INSTRUCTION_ARM(UMULL,
|
|||
|
||||
// Begin load/store definitions
|
||||
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory->load32(cpu->memory, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory->loadU8(cpu->memory, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory->loadU16(cpu->memory, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = cpu->memory->load8(cpu->memory, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = cpu->memory->load16(cpu->memory, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory->store32(cpu->memory, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory->store8(cpu->memory, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory->store16(cpu->memory, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||
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(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;)
|
||||
|
||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT,
|
||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||
cpu->gprs[rd] = cpu->memory->loadU8(cpu->memory, address, ¤tCycles);
|
||||
cpu->gprs[rd] = cpu->memory.loadU8(cpu, address, ¤tCycles);
|
||||
ARMSetPrivilegeMode(cpu, priv);
|
||||
ARM_LOAD_POST_BODY;)
|
||||
|
||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRT,
|
||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||
cpu->gprs[rd] = cpu->memory->load32(cpu->memory, address, ¤tCycles);
|
||||
cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles);
|
||||
ARMSetPrivilegeMode(cpu, priv);
|
||||
ARM_LOAD_POST_BODY;)
|
||||
|
||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRBT,
|
||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||
cpu->memory->store32(cpu->memory, address, cpu->gprs[rd], ¤tCycles);
|
||||
cpu->memory.store32(cpu, address, cpu->gprs[rd], ¤tCycles);
|
||||
ARMSetPrivilegeMode(cpu, priv);
|
||||
ARM_STORE_POST_BODY;)
|
||||
|
||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT,
|
||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||
cpu->memory->store8(cpu->memory, address, cpu->gprs[rd], ¤tCycles);
|
||||
cpu->memory.store8(cpu, address, cpu->gprs[rd], ¤tCycles);
|
||||
ARMSetPrivilegeMode(cpu, priv);
|
||||
ARM_STORE_POST_BODY;)
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM,
|
||||
cpu->gprs[i] = cpu->memory->load32(cpu->memory, addr & 0xFFFFFFFC, 0);,
|
||||
cpu->gprs[i] = cpu->memory.load32(cpu, addr & 0xFFFFFFFC, 0);,
|
||||
++currentCycles;
|
||||
if (rs & 0x8000) {
|
||||
ARM_WRITE_PC;
|
||||
})
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM,
|
||||
cpu->memory->store32(cpu->memory, addr, cpu->gprs[i], 0);,
|
||||
currentCycles += cpu->memory->activeNonseqCycles32 - cpu->memory->activePrefetchCycles32)
|
||||
cpu->memory.store32(cpu, addr, cpu->gprs[i], 0);,
|
||||
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activePrefetchCycles32)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(SWP,
|
||||
int rm = opcode & 0xF;
|
||||
int rd = (opcode >> 12) & 0xF;
|
||||
int rn = (opcode >> 16) & 0xF;
|
||||
int32_t d = cpu->memory->load32(cpu->memory, cpu->gprs[rn], ¤tCycles);
|
||||
cpu->memory->store32(cpu->memory, cpu->gprs[rn], cpu->gprs[rm], ¤tCycles);
|
||||
int32_t d = cpu->memory.load32(cpu, cpu->gprs[rn], ¤tCycles);
|
||||
cpu->memory.store32(cpu, cpu->gprs[rn], cpu->gprs[rm], ¤tCycles);
|
||||
cpu->gprs[rd] = d;)
|
||||
|
||||
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->memory, cpu->gprs[rn], ¤tCycles);
|
||||
cpu->memory->store8(cpu->memory, cpu->gprs[rn], cpu->gprs[rm], ¤tCycles);
|
||||
int32_t d = cpu->memory.loadU8(cpu, cpu->gprs[rn], ¤tCycles);
|
||||
cpu->memory.store8(cpu, cpu->gprs[rn], cpu->gprs[rm], ¤tCycles);
|
||||
cpu->gprs[rd] = d;)
|
||||
|
||||
// End load/store definitions
|
||||
|
@ -702,7 +702,7 @@ DEFINE_INSTRUCTION_ARM(MSRRI,
|
|||
mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK;
|
||||
cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask);)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(SWI, cpu->board->swi32(cpu->board, opcode & 0xFFFFFF))
|
||||
DEFINE_INSTRUCTION_ARM(SWI, cpu->board.swi32(cpu, opcode & 0xFFFFFF))
|
||||
|
||||
#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \
|
||||
EMITTER ## NAME
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define ARM_PREFETCH_CYCLES (1 + cpu->memory->activePrefetchCycles32)
|
||||
#define ARM_PREFETCH_CYCLES (1 + cpu->memory.activePrefetchCycles32)
|
||||
|
||||
struct ARMCore;
|
||||
|
||||
|
|
|
@ -65,18 +65,18 @@
|
|||
cpu->cycles += 4; \
|
||||
}
|
||||
|
||||
#define ARM_STUB cpu->board->hitStub(cpu->board, opcode)
|
||||
#define ARM_ILL cpu->board->hitIllegal(cpu->board, opcode)
|
||||
#define ARM_STUB cpu->board.hitStub(cpu, opcode)
|
||||
#define ARM_ILL cpu->board.hitIllegal(cpu, opcode)
|
||||
|
||||
#define ARM_WRITE_PC \
|
||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC] - WORD_SIZE_ARM); \
|
||||
currentCycles += 2 + cpu->memory->activeNonseqCycles32 + cpu->memory->activePrefetchCycles32;
|
||||
cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC] - WORD_SIZE_ARM); \
|
||||
currentCycles += 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activePrefetchCycles32;
|
||||
|
||||
#define THUMB_WRITE_PC \
|
||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB) + WORD_SIZE_THUMB; \
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC] - WORD_SIZE_THUMB); \
|
||||
currentCycles += 2 + cpu->memory->activeNonseqCycles16 + cpu->memory->activePrefetchCycles16;
|
||||
cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC] - WORD_SIZE_THUMB); \
|
||||
currentCycles += 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activePrefetchCycles16;
|
||||
|
||||
static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {
|
||||
return mode != MODE_SYSTEM && mode != MODE_USER;
|
||||
|
@ -100,7 +100,7 @@ static inline void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode execution
|
|||
static inline void _ARMReadCPSR(struct ARMCore* cpu) {
|
||||
_ARMSetMode(cpu, cpu->cpsr.t);
|
||||
ARMSetPrivilegeMode(cpu, cpu->cpsr.priv);
|
||||
cpu->board->readCPSR(cpu->board);
|
||||
cpu->board.readCPSR(cpu);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,10 +33,10 @@
|
|||
D = M - N; \
|
||||
THUMB_SUBTRACTION_S(m, n, D)
|
||||
|
||||
#define THUMB_PREFETCH_CYCLES (1 + cpu->memory->activePrefetchCycles16)
|
||||
#define THUMB_PREFETCH_CYCLES (1 + cpu->memory.activePrefetchCycles16)
|
||||
|
||||
#define THUMB_STORE_POST_BODY \
|
||||
currentCycles += cpu->memory->activeNonseqCycles16 - cpu->memory->activePrefetchCycles16;
|
||||
currentCycles += cpu->memory.activeNonseqCycles16 - cpu->memory.activePrefetchCycles16;
|
||||
|
||||
#define APPLY(F, ...) F(__VA_ARGS__)
|
||||
|
||||
|
@ -136,12 +136,12 @@ 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->memory, cpu->gprs[rm] + immediate * 4, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRB1, cpu->gprs[rd] = cpu->memory->loadU8(cpu->memory, cpu->gprs[rm] + immediate, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRH1, cpu->gprs[rd] = cpu->memory->loadU16(cpu->memory, cpu->gprs[rm] + immediate * 2, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STR1, cpu->memory->store32(cpu->memory, cpu->gprs[rm] + immediate * 4, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STRB1, cpu->memory->store8(cpu->memory, cpu->gprs[rm] + immediate, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STRH1, cpu->memory->store16(cpu->memory, cpu->gprs[rm] + immediate * 2, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDR1, cpu->gprs[rd] = cpu->memory.load32(cpu, cpu->gprs[rm] + immediate * 4, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRB1, cpu->gprs[rd] = cpu->memory.loadU8(cpu, cpu->gprs[rm] + immediate, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRH1, cpu->gprs[rd] = cpu->memory.loadU16(cpu, cpu->gprs[rm] + immediate * 2, ¤tCycles))
|
||||
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;)
|
||||
|
||||
#define DEFINE_DATA_FORM_1_INSTRUCTION_EX_THUMB(NAME, RM, BODY) \
|
||||
DEFINE_INSTRUCTION_THUMB(NAME, \
|
||||
|
@ -308,9 +308,9 @@ DEFINE_INSTRUCTION_WITH_HIGH_THUMB(MOV3,
|
|||
#define DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(NAME, BODY) \
|
||||
COUNT_3(DEFINE_IMMEDIATE_WITH_REGISTER_EX_THUMB, NAME ## _R, BODY)
|
||||
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(LDR3, cpu->gprs[rd] = cpu->memory->load32(cpu->memory, (cpu->gprs[ARM_PC] & 0xFFFFFFFC) + immediate, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(LDR4, cpu->gprs[rd] = cpu->memory->load32(cpu->memory, cpu->gprs[ARM_SP] + immediate, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(STR3, cpu->memory->store32(cpu->memory, cpu->gprs[ARM_SP] + immediate, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(LDR3, cpu->gprs[rd] = cpu->memory.load32(cpu, (cpu->gprs[ARM_PC] & 0xFFFFFFFC) + immediate, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(LDR4, cpu->gprs[rd] = cpu->memory.load32(cpu, cpu->gprs[ARM_SP] + immediate, ¤tCycles))
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(STR3, cpu->memory.store32(cpu, cpu->gprs[ARM_SP] + immediate, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(ADD5, cpu->gprs[rd] = (cpu->gprs[ARM_PC] & 0xFFFFFFFC) + immediate)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(ADD6, cpu->gprs[rd] = cpu->gprs[ARM_SP] + immediate)
|
||||
|
@ -325,14 +325,14 @@ DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(ADD6, cpu->gprs[rd] = cpu->gprs[ARM_SP] + i
|
|||
#define DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(NAME, BODY) \
|
||||
COUNT_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->memory, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, cpu->gprs[rd] = cpu->memory->loadU8(cpu->memory, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, cpu->gprs[rd] = cpu->memory->loadU16(cpu->memory, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, cpu->gprs[rd] = cpu->memory->load8(cpu->memory, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, cpu->gprs[rd] = cpu->memory->load16(cpu->memory, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, cpu->memory->store32(cpu->memory, 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->memory, 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->memory, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDR2, cpu->gprs[rd] = cpu->memory.load32(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, cpu->gprs[rd] = cpu->memory.loadU8(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, cpu->gprs[rd] = cpu->memory.loadU16(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles))
|
||||
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;)
|
||||
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME, RN, ADDRESS, LOOP, BODY, OP, PRE_BODY, POST_BODY, WRITEBACK) \
|
||||
DEFINE_INSTRUCTION_THUMB(NAME, \
|
||||
|
@ -352,20 +352,20 @@ DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, cpu->memory->store16(cpu->memory, c
|
|||
} \
|
||||
} \
|
||||
POST_BODY; \
|
||||
currentCycles += cpu->memory->waitMultiple(cpu->memory, address, total); \
|
||||
currentCycles += cpu->memory.waitMultiple(cpu, address, total); \
|
||||
WRITEBACK;)
|
||||
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_THUMB(NAME, BODY, WRITEBACK) \
|
||||
COUNT_3(DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB, NAME ## _R, cpu->gprs[rn], (m = 0x01, i = 0; i < 8; m <<= 1, ++i), BODY, +=, , , WRITEBACK)
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_THUMB(LDMIA,
|
||||
cpu->gprs[i] = cpu->memory->load32(cpu->memory, address, 0),
|
||||
cpu->gprs[i] = cpu->memory.load32(cpu, address, 0),
|
||||
if (!((1 << rn) & rs)) {
|
||||
cpu->gprs[rn] = address;
|
||||
})
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_THUMB(STMIA,
|
||||
cpu->memory->store32(cpu->memory, address, cpu->gprs[i], 0),
|
||||
cpu->memory.store32(cpu, address, cpu->gprs[i], 0),
|
||||
THUMB_STORE_POST_BODY;
|
||||
cpu->gprs[rn] = address;)
|
||||
|
||||
|
@ -399,7 +399,7 @@ DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POP,
|
|||
opcode & 0x00FF,
|
||||
cpu->gprs[ARM_SP],
|
||||
(m = 0x01, i = 0; i < 8; m <<= 1, ++i),
|
||||
cpu->gprs[i] = cpu->memory->load32(cpu->memory, address, 0),
|
||||
cpu->gprs[i] = cpu->memory.load32(cpu, address, 0),
|
||||
+=,
|
||||
, ,
|
||||
cpu->gprs[ARM_SP] = address)
|
||||
|
@ -408,10 +408,10 @@ DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPR,
|
|||
opcode & 0x00FF,
|
||||
cpu->gprs[ARM_SP],
|
||||
(m = 0x01, i = 0; i < 8; m <<= 1, ++i),
|
||||
cpu->gprs[i] = cpu->memory->load32(cpu->memory, address, 0),
|
||||
cpu->gprs[i] = cpu->memory.load32(cpu, address, 0),
|
||||
+=,
|
||||
,
|
||||
cpu->gprs[ARM_PC] = cpu->memory->load32(cpu->memory, address, 0) & 0xFFFFFFFE;
|
||||
cpu->gprs[ARM_PC] = cpu->memory.load32(cpu, address, 0) & 0xFFFFFFFE;
|
||||
address += 4;,
|
||||
cpu->gprs[ARM_SP] = address;
|
||||
THUMB_WRITE_PC;)
|
||||
|
@ -420,7 +420,7 @@ DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSH,
|
|||
opcode & 0x00FF,
|
||||
cpu->gprs[ARM_SP] - 4,
|
||||
(m = 0x80, i = 7; m; m >>= 1, --i),
|
||||
cpu->memory->store32(cpu->memory, address, cpu->gprs[i], 0),
|
||||
cpu->memory.store32(cpu, address, cpu->gprs[i], 0),
|
||||
-=,
|
||||
,
|
||||
THUMB_STORE_POST_BODY,
|
||||
|
@ -430,9 +430,9 @@ DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSHR,
|
|||
opcode & 0x00FF,
|
||||
cpu->gprs[ARM_SP] - 4,
|
||||
(m = 0x80, i = 7; m; m >>= 1, --i),
|
||||
cpu->memory->store32(cpu->memory, address, cpu->gprs[i], 0),
|
||||
cpu->memory.store32(cpu, address, cpu->gprs[i], 0),
|
||||
-=,
|
||||
cpu->memory->store32(cpu->memory, address, cpu->gprs[ARM_LR], 0);
|
||||
cpu->memory.store32(cpu, address, cpu->gprs[ARM_LR], 0);
|
||||
address -= 4;,
|
||||
THUMB_STORE_POST_BODY,
|
||||
cpu->gprs[ARM_SP] = address + 4)
|
||||
|
@ -469,7 +469,7 @@ DEFINE_INSTRUCTION_THUMB(BX,
|
|||
ARM_WRITE_PC;
|
||||
})
|
||||
|
||||
DEFINE_INSTRUCTION_THUMB(SWI, cpu->board->swi16(cpu->board, opcode & 0xFF))
|
||||
DEFINE_INSTRUCTION_THUMB(SWI, cpu->board.swi16(cpu, opcode & 0xFF))
|
||||
|
||||
#define DECLARE_INSTRUCTION_THUMB(EMITTER, NAME) \
|
||||
EMITTER ## NAME
|
||||
|
|
|
@ -134,10 +134,10 @@ static void _printHex(struct CLIDebugger* debugger, struct DebugVector* dv) {
|
|||
static inline void _printLine(struct CLIDebugger* debugger, uint32_t address, enum ExecutionMode mode) {
|
||||
// TODO: write a disassembler
|
||||
if (mode == MODE_ARM) {
|
||||
uint32_t instruction = debugger->d.cpu->memory->load32(debugger->d.cpu->memory, address, 0);
|
||||
uint32_t instruction = debugger->d.cpu->memory.load32(debugger->d.cpu, address, 0);
|
||||
printf("%08X\n", instruction);
|
||||
} else {
|
||||
uint16_t instruction = debugger->d.cpu->memory->loadU16(debugger->d.cpu->memory, address, 0);
|
||||
uint16_t instruction = debugger->d.cpu->memory.loadU16(debugger->d.cpu, address, 0);
|
||||
printf("%04X\n", instruction);
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ static void _readByte(struct CLIDebugger* debugger, struct DebugVector* dv) {
|
|||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
uint8_t value = debugger->d.cpu->memory->loadU8(debugger->d.cpu->memory, address, 0);
|
||||
uint8_t value = debugger->d.cpu->memory.loadU8(debugger->d.cpu, address, 0);
|
||||
printf(" 0x%02X\n", value);
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ static void _readHalfword(struct CLIDebugger* debugger, struct DebugVector* dv)
|
|||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
uint16_t value = debugger->d.cpu->memory->loadU16(debugger->d.cpu->memory, address, 0);
|
||||
uint16_t value = debugger->d.cpu->memory.loadU16(debugger->d.cpu, address, 0);
|
||||
printf(" 0x%04X\n", value);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ static void _readWord(struct CLIDebugger* debugger, struct DebugVector* dv) {
|
|||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
uint32_t value = debugger->d.cpu->memory->load32(debugger->d.cpu->memory, address, 0);
|
||||
uint32_t value = debugger->d.cpu->memory.load32(debugger->d.cpu, address, 0);
|
||||
printf(" 0x%08X\n", value);
|
||||
}
|
||||
|
||||
|
@ -221,8 +221,8 @@ static void _setWatchpoint(struct CLIDebugger* debugger, struct DebugVector* dv)
|
|||
printf("%s\n", ERROR_MISSING_ARGS);
|
||||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
ARMDebuggerSetWatchpoint(&debugger->d, address);
|
||||
// TODO: Redo watchpoints
|
||||
(void) (debugger);
|
||||
}
|
||||
|
||||
static void _breakIntoDefault(int signal) {
|
||||
|
|
|
@ -96,9 +96,7 @@ void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address)
|
|||
}
|
||||
|
||||
void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
|
||||
if (debugger->cpu->memory != &debugger->memoryShim.d) {
|
||||
ARMDebuggerInstallMemoryShim(debugger);
|
||||
}
|
||||
// FIXME: Make watchpoints work again
|
||||
struct DebugBreakpoint* watchpoint = malloc(sizeof(struct DebugBreakpoint));
|
||||
watchpoint->address = address;
|
||||
watchpoint->next = debugger->memoryShim.watchpoints;
|
||||
|
|
|
@ -18,8 +18,7 @@ struct DebugBreakpoint {
|
|||
};
|
||||
|
||||
struct DebugMemoryShim {
|
||||
struct ARMMemory d;
|
||||
struct ARMMemory* original;
|
||||
struct ARMMemory original;
|
||||
|
||||
struct ARMDebugger* p;
|
||||
struct DebugBreakpoint* watchpoints;
|
||||
|
|
|
@ -189,10 +189,10 @@ static void _readMemory(struct GDBStub* stub, const char* message) {
|
|||
_error(stub, GDB_BAD_ARGUMENTS);
|
||||
return;
|
||||
}
|
||||
struct ARMMemory* memory = stub->d.memoryShim.original;
|
||||
struct ARMCore* cpu = stub->d.cpu;
|
||||
int writeAddress = 0;
|
||||
for (i = 0; i < size; ++i, writeAddress += 2) {
|
||||
uint8_t byte = memory->load8(memory, address + i, 0);
|
||||
uint8_t byte = cpu->memory.load8(cpu, address + i, 0);
|
||||
_int2hex8(byte, &stub->outgoing[writeAddress]);
|
||||
}
|
||||
stub->outgoing[writeAddress] = 0;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "debugger.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static void ARMDebuggerShim_store32(struct ARMMemory*, uint32_t address, int32_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_store16(struct ARMMemory*, uint32_t address, int16_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_store8(struct ARMMemory*, uint32_t address, int8_t value, int* cycleCounter);
|
||||
|
|
|
@ -397,7 +397,7 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
|
|||
struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
|
||||
dma->nextCount = 4;
|
||||
dma->nextEvent = 0;
|
||||
GBAMemoryUpdateDMAs(&audio->p->memory, -cycles);
|
||||
GBAMemoryUpdateDMAs(audio->p, -cycles);
|
||||
}
|
||||
CircleBufferRead8(&channel->fifo, &channel->sample);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
const uint32_t GBA_BIOS_CHECKSUM = 0xBAAE187F;
|
||||
const uint32_t GBA_DS_BIOS_CHECKSUM = 0xBAAE1880;
|
||||
|
||||
static void _unLz77(struct GBAMemory* memory, uint32_t source, uint8_t* dest);
|
||||
static void _unHuffman(struct GBAMemory* memory, uint32_t source, uint32_t* dest);
|
||||
static void _unRl(struct GBAMemory* memory, uint32_t source, uint8_t* dest);
|
||||
static void _unLz77(struct GBA* gba, uint32_t source, uint8_t* dest);
|
||||
static void _unHuffman(struct GBA* gba, uint32_t source, uint32_t* dest);
|
||||
static void _unRl(struct GBA* gba, uint32_t source, uint8_t* dest);
|
||||
|
||||
static void _RegisterRamReset(struct GBA* gba) {
|
||||
uint32_t registers = gba->cpu.gprs[0];
|
||||
|
@ -29,18 +29,18 @@ static void _CpuSet(struct GBA* gba) {
|
|||
if (wordsize == 4) {
|
||||
source &= 0xFFFFFFFC;
|
||||
dest &= 0xFFFFFFFC;
|
||||
int32_t word = gba->memory.d.load32(&gba->memory.d, source, &gba->cpu.cycles);
|
||||
int32_t word = gba->cpu.memory.load32(&gba->cpu, source, &gba->cpu.cycles);
|
||||
for (i = 0; i < count; ++i) {
|
||||
gba->memory.d.store32(&gba->memory.d, dest + (i << 2), word, &gba->cpu.cycles);
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + (i << 2), word, &gba->cpu.cycles);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
}
|
||||
} else {
|
||||
source &= 0xFFFFFFFE;
|
||||
dest &= 0xFFFFFFFE;
|
||||
uint16_t word = gba->memory.d.load16(&gba->memory.d, source, &gba->cpu.cycles);
|
||||
uint16_t word = gba->cpu.memory.load16(&gba->cpu, source, &gba->cpu.cycles);
|
||||
for (i = 0; i < count; ++i) {
|
||||
gba->memory.d.store16(&gba->memory.d, dest + (i << 1), word, &gba->cpu.cycles);
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
gba->cpu.memory.store16(&gba->cpu, dest + (i << 1), word, &gba->cpu.cycles);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -48,17 +48,17 @@ static void _CpuSet(struct GBA* gba) {
|
|||
source &= 0xFFFFFFFC;
|
||||
dest &= 0xFFFFFFFC;
|
||||
for (i = 0; i < count; ++i) {
|
||||
int32_t word = gba->memory.d.load32(&gba->memory.d, source + (i << 2), &gba->cpu.cycles);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + (i << 2), word, &gba->cpu.cycles);
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
int32_t word = gba->cpu.memory.load32(&gba->cpu, source + (i << 2), &gba->cpu.cycles);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + (i << 2), word, &gba->cpu.cycles);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
}
|
||||
} else {
|
||||
source &= 0xFFFFFFFE;
|
||||
dest &= 0xFFFFFFFE;
|
||||
for (i = 0; i < count; ++i) {
|
||||
uint16_t word = gba->memory.d.load16(&gba->memory.d, source + (i << 1), &gba->cpu.cycles);
|
||||
gba->memory.d.store16(&gba->memory.d, dest + (i << 1), word, &gba->cpu.cycles);
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
uint16_t word = gba->cpu.memory.load16(&gba->cpu, source + (i << 1), &gba->cpu.cycles);
|
||||
gba->cpu.memory.store16(&gba->cpu, dest + (i << 1), word, &gba->cpu.cycles);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,34 +69,34 @@ static void _FastCpuSet(struct GBA* gba) {
|
|||
uint32_t dest = gba->cpu.gprs[1] & 0xFFFFFFFC;
|
||||
uint32_t mode = gba->cpu.gprs[2];
|
||||
int count = mode & 0x000FFFFF;
|
||||
int storeCycles = gba->memory.d.waitMultiple(&gba->memory.d, dest, 4);
|
||||
int storeCycles = gba->cpu.memory.waitMultiple(&gba->cpu, dest, 4);
|
||||
count = ((count + 7) >> 3) << 3;
|
||||
int i;
|
||||
if (mode & 0x01000000) {
|
||||
int32_t word = gba->memory.d.load32(&gba->memory.d, source, &gba->cpu.cycles);
|
||||
int32_t word = gba->cpu.memory.load32(&gba->cpu, source, &gba->cpu.cycles);
|
||||
for (i = 0; i < count; i += 4) {
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 0) << 2), word, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 1) << 2), word, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 2) << 2), word, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 3) << 2), word, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 0) << 2), word, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 1) << 2), word, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 2) << 2), word, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 3) << 2), word, 0);
|
||||
gba->cpu.cycles += storeCycles;
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
}
|
||||
} else {
|
||||
int loadCycles = gba->memory.d.waitMultiple(&gba->memory.d, source, 4);
|
||||
int loadCycles = gba->cpu.memory.waitMultiple(&gba->cpu, source, 4);
|
||||
for (i = 0; i < count; i += 4) {
|
||||
int32_t word0 = gba->memory.d.load32(&gba->memory.d, source + ((i + 0) << 2), 0);
|
||||
int32_t word1 = gba->memory.d.load32(&gba->memory.d, source + ((i + 1) << 2), 0);
|
||||
int32_t word2 = gba->memory.d.load32(&gba->memory.d, source + ((i + 2) << 2), 0);
|
||||
int32_t word3 = gba->memory.d.load32(&gba->memory.d, source + ((i + 3) << 2), 0);
|
||||
int32_t word0 = gba->cpu.memory.load32(&gba->cpu, source + ((i + 0) << 2), 0);
|
||||
int32_t word1 = gba->cpu.memory.load32(&gba->cpu, source + ((i + 1) << 2), 0);
|
||||
int32_t word2 = gba->cpu.memory.load32(&gba->cpu, source + ((i + 2) << 2), 0);
|
||||
int32_t word3 = gba->cpu.memory.load32(&gba->cpu, source + ((i + 3) << 2), 0);
|
||||
gba->cpu.cycles += loadCycles;
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 0) << 2), word0, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 1) << 2), word1, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 2) << 2), word2, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, dest + ((i + 3) << 2), word3, 0);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 0) << 2), word0, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 1) << 2), word1, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 2) << 2), word2, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest + ((i + 3) << 2), word3, 0);
|
||||
gba->cpu.cycles += storeCycles;
|
||||
gba->board.d.processEvents(&gba->board.d);
|
||||
gba->cpu.board.processEvents(&gba->cpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,13 +117,13 @@ static void _BgAffineSet(struct GBA* gba) {
|
|||
// [ sx 0 0 ] [ cos(theta) -sin(theta) 0 ] [ 1 0 cx - ox ] [ A B rx ]
|
||||
// [ 0 sy 0 ] * [ sin(theta) cos(theta) 0 ] * [ 0 1 cy - oy ] = [ C D ry ]
|
||||
// [ 0 0 1 ] [ 0 0 1 ] [ 0 0 1 ] [ 0 0 1 ]
|
||||
ox = gba->memory.d.load32(&gba->memory.d, offset, 0) / 256.f;
|
||||
oy = gba->memory.d.load32(&gba->memory.d, offset + 4, 0) / 256.f;
|
||||
cx = gba->memory.d.load16(&gba->memory.d, offset + 8, 0);
|
||||
cy = gba->memory.d.load16(&gba->memory.d, offset + 10, 0);
|
||||
sx = gba->memory.d.load16(&gba->memory.d, offset + 12, 0) / 256.f;
|
||||
sy = gba->memory.d.load16(&gba->memory.d, offset + 14, 0) / 256.f;
|
||||
theta = (gba->memory.d.loadU16(&gba->memory.d, offset + 16, 0) >> 8) / 128.f * M_PI;
|
||||
ox = gba->cpu.memory.load32(&gba->cpu, offset, 0) / 256.f;
|
||||
oy = gba->cpu.memory.load32(&gba->cpu, offset + 4, 0) / 256.f;
|
||||
cx = gba->cpu.memory.load16(&gba->cpu, offset + 8, 0);
|
||||
cy = gba->cpu.memory.load16(&gba->cpu, offset + 10, 0);
|
||||
sx = gba->cpu.memory.load16(&gba->cpu, offset + 12, 0) / 256.f;
|
||||
sy = gba->cpu.memory.load16(&gba->cpu, offset + 14, 0) / 256.f;
|
||||
theta = (gba->cpu.memory.loadU16(&gba->cpu, offset + 16, 0) >> 8) / 128.f * M_PI;
|
||||
offset += 20;
|
||||
// Rotation
|
||||
a = d = cosf(theta);
|
||||
|
@ -136,12 +136,12 @@ static void _BgAffineSet(struct GBA* gba) {
|
|||
// Translate
|
||||
rx = ox - (a * cx + b * cy);
|
||||
ry = oy - (c * cx + d * cy);
|
||||
gba->memory.d.store16(&gba->memory.d, destination, a * 256, 0);
|
||||
gba->memory.d.store16(&gba->memory.d, destination + 2, b * 256, 0);
|
||||
gba->memory.d.store16(&gba->memory.d, destination + 4, c * 256, 0);
|
||||
gba->memory.d.store16(&gba->memory.d, destination + 6, d * 256, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, destination + 8, rx * 256, 0);
|
||||
gba->memory.d.store32(&gba->memory.d, destination + 12, ry * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination, a * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination + 2, b * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination + 4, c * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination + 6, d * 256, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, destination + 8, rx * 256, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, destination + 12, ry * 256, 0);
|
||||
destination += 16;
|
||||
}
|
||||
}
|
||||
|
@ -157,9 +157,9 @@ static void _ObjAffineSet(struct GBA* gba) {
|
|||
while (i--) {
|
||||
// [ sx 0 ] [ cos(theta) -sin(theta) ] [ A B ]
|
||||
// [ 0 sy ] * [ sin(theta) cos(theta) ] = [ C D ]
|
||||
sx = gba->memory.d.load16(&gba->memory.d, offset, 0) / 256.f;
|
||||
sy = gba->memory.d.load16(&gba->memory.d, offset + 2, 0) / 256.f;
|
||||
theta = (gba->memory.d.loadU16(&gba->memory.d, offset + 4, 0) >> 8) / 128.f * M_PI;
|
||||
sx = gba->cpu.memory.load16(&gba->cpu, offset, 0) / 256.f;
|
||||
sy = gba->cpu.memory.load16(&gba->cpu, offset + 2, 0) / 256.f;
|
||||
theta = (gba->cpu.memory.loadU16(&gba->cpu, offset + 4, 0) >> 8) / 128.f * M_PI;
|
||||
offset += 6;
|
||||
// Rotation
|
||||
a = d = cosf(theta);
|
||||
|
@ -169,21 +169,21 @@ static void _ObjAffineSet(struct GBA* gba) {
|
|||
b *= -sx;
|
||||
c *= sy;
|
||||
d *= sy;
|
||||
gba->memory.d.store16(&gba->memory.d, destination, a * 256, 0);
|
||||
gba->memory.d.store16(&gba->memory.d, destination + diff, b * 256, 0);
|
||||
gba->memory.d.store16(&gba->memory.d, destination + diff * 2, c * 256, 0);
|
||||
gba->memory.d.store16(&gba->memory.d, destination + diff * 3, d * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination, a * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination + diff, b * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination + diff * 2, c * 256, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, destination + diff * 3, d * 256, 0);
|
||||
destination += diff * 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void _MidiKey2Freq(struct GBA* gba) {
|
||||
uint32_t key = gba->memory.d.load32(&gba->memory.d, gba->cpu.gprs[0] + 4, 0);
|
||||
uint32_t key = gba->cpu.memory.load32(&gba->cpu, gba->cpu.gprs[0] + 4, 0);
|
||||
gba->cpu.gprs[0] = key / powf(2, (180.f - gba->cpu.gprs[1] - gba->cpu.gprs[2] / 256.f) / 12.f);
|
||||
}
|
||||
|
||||
void GBASwi16(struct ARMBoard* board, int immediate) {
|
||||
struct GBA* gba = ((struct GBABoard*) board)->p;
|
||||
void GBASwi16(struct ARMCore* cpu, int immediate) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
if (gba->memory.fullBios) {
|
||||
ARMRaiseSWI(&gba->cpu);
|
||||
return;
|
||||
|
@ -253,13 +253,13 @@ void GBASwi16(struct ARMBoard* board, int immediate) {
|
|||
}
|
||||
switch (gba->cpu.gprs[1] >> BASE_OFFSET) {
|
||||
case REGION_WORKING_RAM:
|
||||
_unLz77(&gba->memory, gba->cpu.gprs[0], &((uint8_t*) gba->memory.wram)[(gba->cpu.gprs[1] & (SIZE_WORKING_RAM - 1))]);
|
||||
_unLz77(gba, gba->cpu.gprs[0], &((uint8_t*) gba->memory.wram)[(gba->cpu.gprs[1] & (SIZE_WORKING_RAM - 1))]);
|
||||
break;
|
||||
case REGION_WORKING_IRAM:
|
||||
_unLz77(&gba->memory, gba->cpu.gprs[0], &((uint8_t*) gba->memory.iwram)[(gba->cpu.gprs[1] & (SIZE_WORKING_IRAM - 1))]);
|
||||
_unLz77(gba, gba->cpu.gprs[0], &((uint8_t*) gba->memory.iwram)[(gba->cpu.gprs[1] & (SIZE_WORKING_IRAM - 1))]);
|
||||
break;
|
||||
case REGION_VRAM:
|
||||
_unLz77(&gba->memory, gba->cpu.gprs[0], &((uint8_t*) gba->video.renderer->vram)[(gba->cpu.gprs[1] & 0x0001FFFF)]);
|
||||
_unLz77(gba, gba->cpu.gprs[0], &((uint8_t*) gba->video.renderer->vram)[(gba->cpu.gprs[1] & 0x0001FFFF)]);
|
||||
break;
|
||||
default:
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad LZ77 destination");
|
||||
|
@ -273,13 +273,13 @@ void GBASwi16(struct ARMBoard* board, int immediate) {
|
|||
}
|
||||
switch (gba->cpu.gprs[1] >> BASE_OFFSET) {
|
||||
case REGION_WORKING_RAM:
|
||||
_unHuffman(&gba->memory, gba->cpu.gprs[0], &((uint32_t*) gba->memory.wram)[(gba->cpu.gprs[1] & (SIZE_WORKING_RAM - 3)) >> 2]);
|
||||
_unHuffman(gba, gba->cpu.gprs[0], &((uint32_t*) gba->memory.wram)[(gba->cpu.gprs[1] & (SIZE_WORKING_RAM - 3)) >> 2]);
|
||||
break;
|
||||
case REGION_WORKING_IRAM:
|
||||
_unHuffman(&gba->memory, gba->cpu.gprs[0], &((uint32_t*) gba->memory.iwram)[(gba->cpu.gprs[1] & (SIZE_WORKING_IRAM - 3)) >> 2]);
|
||||
_unHuffman(gba, gba->cpu.gprs[0], &((uint32_t*) gba->memory.iwram)[(gba->cpu.gprs[1] & (SIZE_WORKING_IRAM - 3)) >> 2]);
|
||||
break;
|
||||
case REGION_VRAM:
|
||||
_unHuffman(&gba->memory, gba->cpu.gprs[0], &((uint32_t*) gba->video.renderer->vram)[(gba->cpu.gprs[1] & 0x0001FFFC) >> 2]);
|
||||
_unHuffman(gba, gba->cpu.gprs[0], &((uint32_t*) gba->video.renderer->vram)[(gba->cpu.gprs[1] & 0x0001FFFC) >> 2]);
|
||||
break;
|
||||
default:
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad Huffman destination");
|
||||
|
@ -294,13 +294,13 @@ void GBASwi16(struct ARMBoard* board, int immediate) {
|
|||
}
|
||||
switch (gba->cpu.gprs[1] >> BASE_OFFSET) {
|
||||
case REGION_WORKING_RAM:
|
||||
_unRl(&gba->memory, gba->cpu.gprs[0], &((uint8_t*) gba->memory.wram)[(gba->cpu.gprs[1] & (SIZE_WORKING_RAM - 1))]);
|
||||
_unRl(gba, gba->cpu.gprs[0], &((uint8_t*) gba->memory.wram)[(gba->cpu.gprs[1] & (SIZE_WORKING_RAM - 1))]);
|
||||
break;
|
||||
case REGION_WORKING_IRAM:
|
||||
_unRl(&gba->memory, gba->cpu.gprs[0], &((uint8_t*) gba->memory.iwram)[(gba->cpu.gprs[1] & (SIZE_WORKING_IRAM - 1))]);
|
||||
_unRl(gba, gba->cpu.gprs[0], &((uint8_t*) gba->memory.iwram)[(gba->cpu.gprs[1] & (SIZE_WORKING_IRAM - 1))]);
|
||||
break;
|
||||
case REGION_VRAM:
|
||||
_unRl(&gba->memory, gba->cpu.gprs[0], &((uint8_t*) gba->video.renderer->vram)[(gba->cpu.gprs[1] & 0x0001FFFF)]);
|
||||
_unRl(gba, gba->cpu.gprs[0], &((uint8_t*) gba->video.renderer->vram)[(gba->cpu.gprs[1] & 0x0001FFFF)]);
|
||||
break;
|
||||
default:
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad RL destination");
|
||||
|
@ -315,8 +315,8 @@ void GBASwi16(struct ARMBoard* board, int immediate) {
|
|||
}
|
||||
}
|
||||
|
||||
void GBASwi32(struct ARMBoard* board, int immediate) {
|
||||
GBASwi16(board, immediate >> 16);
|
||||
void GBASwi32(struct ARMCore* cpu, int immediate) {
|
||||
GBASwi16(cpu, immediate >> 16);
|
||||
}
|
||||
|
||||
uint32_t GBAChecksum(uint32_t* memory, size_t size) {
|
||||
|
@ -328,8 +328,8 @@ uint32_t GBAChecksum(uint32_t* memory, size_t size) {
|
|||
return sum;
|
||||
}
|
||||
|
||||
static void _unLz77(struct GBAMemory* memory, uint32_t source, uint8_t* dest) {
|
||||
int remaining = (memory->d.load32(&memory->d, source, 0) & 0xFFFFFF00) >> 8;
|
||||
static void _unLz77(struct GBA* gba, uint32_t source, uint8_t* dest) {
|
||||
int remaining = (gba->cpu.memory.load32(&gba->cpu, source, 0) & 0xFFFFFF00) >> 8;
|
||||
// We assume the signature byte (0x10) is correct
|
||||
int blockheader;
|
||||
uint32_t sPointer = source + 4;
|
||||
|
@ -342,7 +342,7 @@ static void _unLz77(struct GBAMemory* memory, uint32_t source, uint8_t* dest) {
|
|||
if (blocksRemaining) {
|
||||
if (blockheader & 0x80) {
|
||||
// Compressed
|
||||
block = memory->d.loadU8(&memory->d, sPointer, 0) | (memory->d.loadU8(&memory->d, sPointer + 1, 0) << 8);
|
||||
block = gba->cpu.memory.loadU8(&gba->cpu, sPointer, 0) | (gba->cpu.memory.loadU8(&gba->cpu, sPointer + 1, 0) << 8);
|
||||
sPointer += 2;
|
||||
disp = dPointer - (((block & 0x000F) << 8) | ((block & 0xFF00) >> 8)) - 1;
|
||||
bytes = ((block & 0x00F0) >> 4) + 3;
|
||||
|
@ -354,33 +354,33 @@ static void _unLz77(struct GBAMemory* memory, uint32_t source, uint8_t* dest) {
|
|||
}
|
||||
} else {
|
||||
// Uncompressed
|
||||
*dPointer = memory->d.loadU8(&memory->d, sPointer++, 0);
|
||||
*dPointer = gba->cpu.memory.loadU8(&gba->cpu, sPointer++, 0);
|
||||
++dPointer;
|
||||
--remaining;
|
||||
}
|
||||
blockheader <<= 1;
|
||||
--blocksRemaining;
|
||||
} else {
|
||||
blockheader = memory->d.loadU8(&memory->d, sPointer++, 0);
|
||||
blockheader = gba->cpu.memory.loadU8(&gba->cpu, sPointer++, 0);
|
||||
blocksRemaining = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _unHuffman(struct GBAMemory* memory, uint32_t source, uint32_t* dest) {
|
||||
static void _unHuffman(struct GBA* gba, uint32_t source, uint32_t* dest) {
|
||||
source = source & 0xFFFFFFFC;
|
||||
uint32_t header = memory->d.load32(&memory->d, source, 0);
|
||||
uint32_t header = gba->cpu.memory.load32(&gba->cpu, source, 0);
|
||||
int remaining = header >> 8;
|
||||
int bits = header & 0xF;
|
||||
if (32 % bits) {
|
||||
GBALog(memory->p, GBA_LOG_STUB, "Unimplemented unaligned Huffman");
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented unaligned Huffman");
|
||||
return;
|
||||
}
|
||||
int padding = (4 - remaining) & 0x3;
|
||||
remaining &= 0xFFFFFFFC;
|
||||
// We assume the signature byte (0x20) is correct
|
||||
//var tree = [];
|
||||
int treesize = (memory->d.loadU8(&memory->d, source + 4, 0) << 1) + 1;
|
||||
int treesize = (gba->cpu.memory.loadU8(&gba->cpu, source + 4, 0) << 1) + 1;
|
||||
int block = 0;
|
||||
uint32_t treeBase = source + 5;
|
||||
uint32_t sPointer = source + 5 + treesize;
|
||||
|
@ -397,28 +397,28 @@ static void _unHuffman(struct GBAMemory* memory, uint32_t source, uint32_t* dest
|
|||
int bitsRemaining;
|
||||
int readBits;
|
||||
int bitsSeen = 0;
|
||||
node.packed = memory->d.load8(&memory->d, nPointer, 0);
|
||||
node.packed = gba->cpu.memory.load8(&gba->cpu, nPointer, 0);
|
||||
while (remaining > 0) {
|
||||
uint32_t bitstream = memory->d.load32(&memory->d, sPointer, 0);
|
||||
uint32_t bitstream = gba->cpu.memory.load32(&gba->cpu, sPointer, 0);
|
||||
sPointer += 4;
|
||||
for (bitsRemaining = 32; bitsRemaining > 0; --bitsRemaining, bitstream <<= 1) {
|
||||
uint32_t next = (nPointer & ~1) + node.offset * 2 + 2;
|
||||
if (bitstream & 0x80000000) {
|
||||
// Go right
|
||||
if (node.rTerm) {
|
||||
readBits = memory->d.load8(&memory->d, next + 1, 0);
|
||||
readBits = gba->cpu.memory.load8(&gba->cpu, next + 1, 0);
|
||||
} else {
|
||||
nPointer = next + 1;
|
||||
node.packed = memory->d.load8(&memory->d, nPointer, 0);
|
||||
node.packed = gba->cpu.memory.load8(&gba->cpu, nPointer, 0);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Go left
|
||||
if (node.lTerm) {
|
||||
readBits = memory->d.load8(&memory->d, next, 0);
|
||||
readBits = gba->cpu.memory.load8(&gba->cpu, next, 0);
|
||||
} else {
|
||||
nPointer = next;
|
||||
node.packed = memory->d.load8(&memory->d, nPointer, 0);
|
||||
node.packed = gba->cpu.memory.load8(&gba->cpu, nPointer, 0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ static void _unHuffman(struct GBAMemory* memory, uint32_t source, uint32_t* dest
|
|||
block |= (readBits & ((1 << bits) - 1)) << bitsSeen;
|
||||
bitsSeen += bits;
|
||||
nPointer = treeBase;
|
||||
node.packed = memory->d.load8(&memory->d, nPointer, 0);
|
||||
node.packed = gba->cpu.memory.load8(&gba->cpu, nPointer, 0);
|
||||
if (bitsSeen == 32) {
|
||||
bitsSeen = 0;
|
||||
*dPointer = block;
|
||||
|
@ -442,9 +442,9 @@ static void _unHuffman(struct GBAMemory* memory, uint32_t source, uint32_t* dest
|
|||
}
|
||||
}
|
||||
|
||||
static void _unRl(struct GBAMemory* memory, uint32_t source, uint8_t* dest) {
|
||||
static void _unRl(struct GBA* gba, uint32_t source, uint8_t* dest) {
|
||||
source = source & 0xFFFFFFFC;
|
||||
int remaining = (memory->d.load32(&memory->d, source, 0) & 0xFFFFFF00) >> 8;
|
||||
int remaining = (gba->cpu.memory.load32(&gba->cpu, source, 0) & 0xFFFFFF00) >> 8;
|
||||
int padding = (4 - remaining) & 0x3;
|
||||
// We assume the signature byte (0x30) is correct
|
||||
int blockheader;
|
||||
|
@ -452,12 +452,12 @@ static void _unRl(struct GBAMemory* memory, uint32_t source, uint8_t* dest) {
|
|||
uint32_t sPointer = source + 4;
|
||||
uint8_t* dPointer = dest;
|
||||
while (remaining > 0) {
|
||||
blockheader = memory->d.loadU8(&memory->d, sPointer++, 0);
|
||||
blockheader = gba->cpu.memory.loadU8(&gba->cpu, sPointer++, 0);
|
||||
if (blockheader & 0x80) {
|
||||
// Compressed
|
||||
blockheader &= 0x7F;
|
||||
blockheader += 3;
|
||||
block = memory->d.loadU8(&memory->d, sPointer++, 0);
|
||||
block = gba->cpu.memory.loadU8(&gba->cpu, sPointer++, 0);
|
||||
while (blockheader-- && remaining) {
|
||||
--remaining;
|
||||
*dPointer = block;
|
||||
|
@ -468,7 +468,7 @@ static void _unRl(struct GBAMemory* memory, uint32_t source, uint8_t* dest) {
|
|||
blockheader++;
|
||||
while (blockheader-- && remaining) {
|
||||
--remaining;
|
||||
*dPointer = memory->d.loadU8(&memory->d, sPointer++, 0);
|
||||
*dPointer = gba->cpu.memory.loadU8(&gba->cpu, sPointer++, 0);
|
||||
++dPointer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
#include "arm.h"
|
||||
|
||||
void GBASwi16(struct ARMBoard* board, int immediate);
|
||||
void GBASwi32(struct ARMBoard* board, int immediate);
|
||||
void GBASwi16(struct ARMCore* cpu, int immediate);
|
||||
void GBASwi32(struct ARMCore* cpu, int immediate);
|
||||
|
||||
uint32_t GBAChecksum(uint32_t* memory, size_t size);
|
||||
const uint32_t GBA_BIOS_CHECKSUM;
|
||||
|
|
|
@ -200,28 +200,28 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
break;
|
||||
|
||||
case REG_DMA0CNT_LO:
|
||||
GBAMemoryWriteDMACNT_LO(&gba->memory, 0, value);
|
||||
GBAMemoryWriteDMACNT_LO(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA0CNT_HI:
|
||||
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value);
|
||||
value = GBAMemoryWriteDMACNT_HI(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA1CNT_LO:
|
||||
GBAMemoryWriteDMACNT_LO(&gba->memory, 1, value);
|
||||
GBAMemoryWriteDMACNT_LO(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA1CNT_HI:
|
||||
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value);
|
||||
value = GBAMemoryWriteDMACNT_HI(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA2CNT_LO:
|
||||
GBAMemoryWriteDMACNT_LO(&gba->memory, 2, value);
|
||||
GBAMemoryWriteDMACNT_LO(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA2CNT_HI:
|
||||
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value);
|
||||
value = GBAMemoryWriteDMACNT_HI(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA3CNT_LO:
|
||||
GBAMemoryWriteDMACNT_LO(&gba->memory, 3, value);
|
||||
GBAMemoryWriteDMACNT_LO(gba, 3, value);
|
||||
break;
|
||||
case REG_DMA3CNT_HI:
|
||||
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value);
|
||||
value = GBAMemoryWriteDMACNT_HI(gba, 3, value);
|
||||
break;
|
||||
|
||||
// Timers
|
||||
|
@ -269,7 +269,7 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
|
||||
// Interrupts and misc
|
||||
case REG_WAITCNT:
|
||||
GBAAdjustWaitstates(&gba->memory, value);
|
||||
GBAAdjustWaitstates(gba, value);
|
||||
break;
|
||||
case REG_IE:
|
||||
GBAWriteIE(gba, value);
|
||||
|
@ -325,28 +325,28 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
|
|||
GBAAudioWriteFIFO(&gba->audio, address, value);
|
||||
break;
|
||||
case REG_DMA0SAD_LO:
|
||||
GBAMemoryWriteDMASAD(&gba->memory, 0, value);
|
||||
GBAMemoryWriteDMASAD(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA0DAD_LO:
|
||||
GBAMemoryWriteDMADAD(&gba->memory, 0, value);
|
||||
GBAMemoryWriteDMADAD(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA1SAD_LO:
|
||||
GBAMemoryWriteDMASAD(&gba->memory, 1, value);
|
||||
GBAMemoryWriteDMASAD(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA1DAD_LO:
|
||||
GBAMemoryWriteDMADAD(&gba->memory, 1, value);
|
||||
GBAMemoryWriteDMADAD(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA2SAD_LO:
|
||||
GBAMemoryWriteDMASAD(&gba->memory, 2, value);
|
||||
GBAMemoryWriteDMASAD(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA2DAD_LO:
|
||||
GBAMemoryWriteDMADAD(&gba->memory, 2, value);
|
||||
GBAMemoryWriteDMADAD(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA3SAD_LO:
|
||||
GBAMemoryWriteDMASAD(&gba->memory, 3, value);
|
||||
GBAMemoryWriteDMASAD(gba, 3, value);
|
||||
break;
|
||||
case REG_DMA3DAD_LO:
|
||||
GBAMemoryWriteDMADAD(&gba->memory, 3, value);
|
||||
GBAMemoryWriteDMADAD(gba, 3, value);
|
||||
break;
|
||||
default:
|
||||
GBAIOWrite(gba, address, value & 0xFFFF);
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
#include "hle-bios.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region);
|
||||
static int GBAWaitMultiple(struct ARMMemory* memory, uint32_t startAddress, int count);
|
||||
static void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* info);
|
||||
static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
|
||||
static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count);
|
||||
static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);
|
||||
|
||||
static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
|
||||
static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };
|
||||
|
@ -18,99 +18,100 @@ static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
|
|||
static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
|
||||
static const int DMA_OFFSET[] = { 1, -1, 0, 1 };
|
||||
|
||||
void GBAMemoryInit(struct GBAMemory* memory) {
|
||||
memory->d.load32 = GBALoad32;
|
||||
memory->d.load16 = GBALoad16;
|
||||
memory->d.loadU16 = GBALoadU16;
|
||||
memory->d.load8 = GBALoad8;
|
||||
memory->d.loadU8 = GBALoadU8;
|
||||
memory->d.store32 = GBAStore32;
|
||||
memory->d.store16 = GBAStore16;
|
||||
memory->d.store8 = GBAStore8;
|
||||
void GBAMemoryInit(struct GBA* gba) {
|
||||
gba->cpu.memory.load32 = GBALoad32;
|
||||
gba->cpu.memory.load16 = GBALoad16;
|
||||
gba->cpu.memory.loadU16 = GBALoadU16;
|
||||
gba->cpu.memory.load8 = GBALoad8;
|
||||
gba->cpu.memory.loadU8 = GBALoadU8;
|
||||
gba->cpu.memory.store32 = GBAStore32;
|
||||
gba->cpu.memory.store16 = GBAStore16;
|
||||
gba->cpu.memory.store8 = GBAStore8;
|
||||
|
||||
memory->bios = (uint32_t*) hleBios;
|
||||
memory->fullBios = 0;
|
||||
memory->wram = anonymousMemoryMap(SIZE_WORKING_RAM);
|
||||
memory->iwram = anonymousMemoryMap(SIZE_WORKING_IRAM);
|
||||
memory->rom = 0;
|
||||
memory->gpio.p = memory->p;
|
||||
memset(memory->io, 0, sizeof(memory->io));
|
||||
memset(memory->dma, 0, sizeof(memory->dma));
|
||||
gba->memory.bios = (uint32_t*) hleBios;
|
||||
gba->memory.fullBios = 0;
|
||||
gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
|
||||
gba->memory.iwram = anonymousMemoryMap(SIZE_WORKING_IRAM);
|
||||
gba->memory.rom = 0;
|
||||
gba->memory.gpio.p = gba;
|
||||
memset(gba->memory.io, 0, sizeof(gba->memory.io));
|
||||
memset(gba->memory.dma, 0, sizeof(gba->memory.dma));
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
memory->dma[i].count = 0x10000;
|
||||
memory->dma[i].nextEvent = INT_MAX;
|
||||
gba->memory.dma[i].count = 0x10000;
|
||||
gba->memory.dma[i].nextEvent = INT_MAX;
|
||||
}
|
||||
memory->activeDMA = -1;
|
||||
memory->nextDMA = INT_MAX;
|
||||
memory->eventDiff = 0;
|
||||
gba->memory.activeDMA = -1;
|
||||
gba->memory.nextDMA = INT_MAX;
|
||||
gba->memory.eventDiff = 0;
|
||||
|
||||
if (!memory->wram || !memory->iwram) {
|
||||
GBAMemoryDeinit(memory);
|
||||
GBALog(memory->p, GBA_LOG_FATAL, "Could not map memory");
|
||||
if (!gba->memory.wram || !gba->memory.iwram) {
|
||||
GBAMemoryDeinit(gba);
|
||||
GBALog(gba, GBA_LOG_FATAL, "Could not map memory");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
memory->waitstates16[i] = GBA_BASE_WAITSTATES[i];
|
||||
memory->waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
|
||||
memory->waitstatesPrefetch16[i] = GBA_BASE_WAITSTATES_SEQ[i];
|
||||
memory->waitstates32[i] = GBA_BASE_WAITSTATES_32[i];
|
||||
memory->waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
|
||||
memory->waitstatesPrefetch32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
|
||||
gba->memory.waitstates16[i] = GBA_BASE_WAITSTATES[i];
|
||||
gba->memory.waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
|
||||
gba->memory.waitstatesPrefetch16[i] = GBA_BASE_WAITSTATES_SEQ[i];
|
||||
gba->memory.waitstates32[i] = GBA_BASE_WAITSTATES_32[i];
|
||||
gba->memory.waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
|
||||
gba->memory.waitstatesPrefetch32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
|
||||
}
|
||||
for (; i < 256; ++i) {
|
||||
memory->waitstates16[i] = 0;
|
||||
memory->waitstatesSeq16[i] = 0;
|
||||
memory->waitstatesPrefetch16[i] = 0;
|
||||
memory->waitstates32[i] = 0;
|
||||
memory->waitstatesSeq32[i] = 0;
|
||||
memory->waitstatesPrefetch32[i] = 0;
|
||||
gba->memory.waitstates16[i] = 0;
|
||||
gba->memory.waitstatesSeq16[i] = 0;
|
||||
gba->memory.waitstatesPrefetch16[i] = 0;
|
||||
gba->memory.waitstates32[i] = 0;
|
||||
gba->memory.waitstatesSeq32[i] = 0;
|
||||
gba->memory.waitstatesPrefetch32[i] = 0;
|
||||
}
|
||||
|
||||
memory->activeRegion = -1;
|
||||
memory->d.activeRegion = 0;
|
||||
memory->d.activeMask = 0;
|
||||
memory->d.setActiveRegion = GBASetActiveRegion;
|
||||
memory->d.activePrefetchCycles32 = 0;
|
||||
memory->d.activePrefetchCycles16 = 0;
|
||||
memory->biosPrefetch = 0;
|
||||
memory->d.waitMultiple = GBAWaitMultiple;
|
||||
gba->memory.activeRegion = -1;
|
||||
gba->cpu.memory.activeRegion = 0;
|
||||
gba->cpu.memory.activeMask = 0;
|
||||
gba->cpu.memory.setActiveRegion = GBASetActiveRegion;
|
||||
gba->cpu.memory.activePrefetchCycles32 = 0;
|
||||
gba->cpu.memory.activePrefetchCycles16 = 0;
|
||||
gba->memory.biosPrefetch = 0;
|
||||
gba->cpu.memory.waitMultiple = GBAWaitMultiple;
|
||||
}
|
||||
|
||||
void GBAMemoryDeinit(struct GBAMemory* memory) {
|
||||
mappedMemoryFree(memory->wram, SIZE_WORKING_RAM);
|
||||
mappedMemoryFree(memory->iwram, SIZE_WORKING_IRAM);
|
||||
GBASavedataDeinit(&memory->savedata);
|
||||
void GBAMemoryDeinit(struct GBA* gba) {
|
||||
mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
|
||||
mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
|
||||
GBASavedataDeinit(&gba->memory.savedata);
|
||||
}
|
||||
|
||||
static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
|
||||
int newRegion = address >> BASE_OFFSET;
|
||||
if (newRegion == gbaMemory->activeRegion) {
|
||||
if (newRegion == memory->activeRegion) {
|
||||
return;
|
||||
}
|
||||
if (gbaMemory->activeRegion == REGION_BIOS) {
|
||||
gbaMemory->biosPrefetch = memory->load32(memory, gbaMemory->p->cpu.currentPC + WORD_SIZE_ARM * 2, 0);
|
||||
if (memory->activeRegion == REGION_BIOS) {
|
||||
memory->biosPrefetch = cpu->memory.load32(cpu, cpu->currentPC + WORD_SIZE_ARM * 2, 0);
|
||||
}
|
||||
gbaMemory->activeRegion = newRegion;
|
||||
memory->activePrefetchCycles32 = gbaMemory->waitstatesPrefetch32[gbaMemory->activeRegion];
|
||||
memory->activePrefetchCycles16 = gbaMemory->waitstatesPrefetch16[gbaMemory->activeRegion];
|
||||
memory->activeNonseqCycles32 = gbaMemory->waitstates32[gbaMemory->activeRegion];
|
||||
memory->activeNonseqCycles16 = gbaMemory->waitstates16[gbaMemory->activeRegion];
|
||||
memory->activeRegion = newRegion;
|
||||
cpu->memory.activePrefetchCycles32 = memory->waitstatesPrefetch32[memory->activeRegion];
|
||||
cpu->memory.activePrefetchCycles16 = memory->waitstatesPrefetch16[memory->activeRegion];
|
||||
cpu->memory.activeNonseqCycles32 = memory->waitstates32[memory->activeRegion];
|
||||
cpu->memory.activeNonseqCycles16 = memory->waitstates16[memory->activeRegion];
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_BIOS:
|
||||
memory->activeRegion = gbaMemory->bios;
|
||||
memory->activeMask = SIZE_BIOS - 1;
|
||||
cpu->memory.activeRegion = memory->bios;
|
||||
cpu->memory.activeMask = SIZE_BIOS - 1;
|
||||
break;
|
||||
case BASE_WORKING_RAM:
|
||||
memory->activeRegion = gbaMemory->wram;
|
||||
memory->activeMask = SIZE_WORKING_RAM - 1;
|
||||
cpu->memory.activeRegion = memory->wram;
|
||||
cpu->memory.activeMask = SIZE_WORKING_RAM - 1;
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
memory->activeRegion = gbaMemory->iwram;
|
||||
memory->activeMask = SIZE_WORKING_IRAM - 1;
|
||||
cpu->memory.activeRegion = memory->iwram;
|
||||
cpu->memory.activeMask = SIZE_WORKING_IRAM - 1;
|
||||
break;
|
||||
case BASE_CART0:
|
||||
case BASE_CART0_EX:
|
||||
|
@ -118,52 +119,53 @@ static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) {
|
|||
case BASE_CART1_EX:
|
||||
case BASE_CART2:
|
||||
case BASE_CART2_EX:
|
||||
memory->activeRegion = gbaMemory->rom;
|
||||
memory->activeMask = SIZE_CART0 - 1;
|
||||
cpu->memory.activeRegion = memory->rom;
|
||||
cpu->memory.activeMask = SIZE_CART0 - 1;
|
||||
break;
|
||||
default:
|
||||
memory->activeRegion = 0;
|
||||
memory->activeMask = 0;
|
||||
GBALog(gbaMemory->p, GBA_LOG_FATAL, "Jumped to invalid address");
|
||||
cpu->memory.activeRegion = 0;
|
||||
cpu->memory.activeMask = 0;
|
||||
GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
int32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
uint32_t value = 0;
|
||||
int wait = 0;
|
||||
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_BIOS:
|
||||
if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) {
|
||||
if (cpu->currentPC >> BASE_OFFSET == REGION_BIOS) {
|
||||
if (address < SIZE_BIOS) {
|
||||
LOAD_32(value, address, gbaMemory->bios);
|
||||
LOAD_32(value, address, memory->bios);
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
} else {
|
||||
value = gbaMemory->biosPrefetch;
|
||||
value = memory->biosPrefetch;
|
||||
}
|
||||
break;
|
||||
case BASE_WORKING_RAM:
|
||||
LOAD_32(value, address & (SIZE_WORKING_RAM - 1), gbaMemory->wram);
|
||||
wait = gbaMemory->waitstates32[REGION_WORKING_RAM];
|
||||
LOAD_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
|
||||
wait = memory->waitstates32[REGION_WORKING_RAM];
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), gbaMemory->iwram);
|
||||
LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
|
||||
break;
|
||||
case BASE_IO:
|
||||
value = GBAIORead(gbaMemory->p, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gbaMemory->p, (address & (SIZE_IO - 1)) | 2) << 16);
|
||||
value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
|
||||
break;
|
||||
case BASE_PALETTE_RAM:
|
||||
LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gbaMemory->p->video.palette);
|
||||
LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
|
||||
break;
|
||||
case BASE_VRAM:
|
||||
LOAD_32(value, address & 0x0001FFFF, gbaMemory->p->video.renderer->vram);
|
||||
LOAD_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
|
||||
break;
|
||||
case BASE_OAM:
|
||||
LOAD_32(value, address & (SIZE_OAM - 1), gbaMemory->p->video.oam.raw);
|
||||
LOAD_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
|
||||
break;
|
||||
case BASE_CART0:
|
||||
case BASE_CART0_EX:
|
||||
|
@ -171,21 +173,21 @@ int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter)
|
|||
case BASE_CART1_EX:
|
||||
case BASE_CART2:
|
||||
case BASE_CART2_EX:
|
||||
wait = gbaMemory->waitstates32[address >> BASE_OFFSET];
|
||||
if ((address & (SIZE_CART0 - 1)) < gbaMemory->romSize) {
|
||||
LOAD_32(value, address & (SIZE_CART0 - 1), gbaMemory->rom);
|
||||
wait = memory->waitstates32[address >> BASE_OFFSET];
|
||||
if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
|
||||
LOAD_32(value, address & (SIZE_CART0 - 1), memory->rom);
|
||||
}
|
||||
break;
|
||||
case BASE_CART_SRAM:
|
||||
case BASE_CART_SRAM_MIRROR:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load32: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load32: 0x%08X", address);
|
||||
break;
|
||||
default:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address);
|
||||
if (gbaMemory->p->cpu.executionMode == MODE_ARM) {
|
||||
value = memory->load32(memory, gbaMemory->p->cpu.currentPC + WORD_SIZE_ARM * 2, 0);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address);
|
||||
if (cpu->executionMode == MODE_ARM) {
|
||||
value = cpu->memory.load32(&gba->cpu, cpu->currentPC + WORD_SIZE_ARM * 2, 0);
|
||||
} else {
|
||||
value = memory->load16(memory, gbaMemory->p->cpu.currentPC + WORD_SIZE_THUMB * 2, 0);
|
||||
value = cpu->memory.load16(&gba->cpu, cpu->currentPC + WORD_SIZE_THUMB * 2, 0);
|
||||
value |= value << 16;
|
||||
}
|
||||
break;
|
||||
|
@ -200,71 +202,72 @@ int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter)
|
|||
return (value >> rotate) | (value << (32 - rotate));
|
||||
}
|
||||
|
||||
uint16_t GBALoadU16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
||||
return GBALoad16(memory, address, cycleCounter);
|
||||
uint16_t GBALoadU16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
return GBALoad16(cpu, address, cycleCounter);
|
||||
}
|
||||
|
||||
int16_t GBALoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
int16_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
uint16_t value = 0;
|
||||
int wait = 0;
|
||||
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_BIOS:
|
||||
if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) {
|
||||
if (cpu->currentPC >> BASE_OFFSET == REGION_BIOS) {
|
||||
if (address < SIZE_BIOS) {
|
||||
LOAD_16(value, address, gbaMemory->bios);
|
||||
LOAD_16(value, address, memory->bios);
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
} else {
|
||||
value = gbaMemory->biosPrefetch;
|
||||
value = memory->biosPrefetch;
|
||||
}
|
||||
break;
|
||||
case BASE_WORKING_RAM:
|
||||
LOAD_16(value, address & (SIZE_WORKING_RAM - 1), gbaMemory->wram);
|
||||
wait = gbaMemory->waitstates16[REGION_WORKING_RAM];
|
||||
LOAD_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
|
||||
wait = memory->waitstates16[REGION_WORKING_RAM];
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), gbaMemory->iwram);
|
||||
LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
|
||||
break;
|
||||
case BASE_IO:
|
||||
value = GBAIORead(gbaMemory->p, address & (SIZE_IO - 1));
|
||||
value = GBAIORead(gba, address & (SIZE_IO - 1));
|
||||
break;
|
||||
case BASE_PALETTE_RAM:
|
||||
LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gbaMemory->p->video.palette);
|
||||
LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
|
||||
break;
|
||||
case BASE_VRAM:
|
||||
LOAD_16(value, address & 0x0001FFFF, gbaMemory->p->video.renderer->vram);
|
||||
LOAD_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
|
||||
break;
|
||||
case BASE_OAM:
|
||||
LOAD_16(value, address & (SIZE_OAM - 1), gbaMemory->p->video.oam.raw);
|
||||
LOAD_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
|
||||
break;
|
||||
case BASE_CART0:
|
||||
case BASE_CART0_EX:
|
||||
case BASE_CART1:
|
||||
case BASE_CART1_EX:
|
||||
case BASE_CART2:
|
||||
wait = gbaMemory->waitstates16[address >> BASE_OFFSET];
|
||||
if ((address & (SIZE_CART0 - 1)) < gbaMemory->romSize) {
|
||||
LOAD_16(value, address & (SIZE_CART0 - 1), gbaMemory->rom);
|
||||
wait = memory->waitstates16[address >> BASE_OFFSET];
|
||||
if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
|
||||
LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
|
||||
}
|
||||
break;
|
||||
case BASE_CART2_EX:
|
||||
wait = gbaMemory->waitstates16[address >> BASE_OFFSET];
|
||||
if (gbaMemory->savedata.type == SAVEDATA_EEPROM) {
|
||||
value = GBASavedataReadEEPROM(&gbaMemory->savedata);
|
||||
} else if ((address & (SIZE_CART0 - 1)) < gbaMemory->romSize) {
|
||||
LOAD_16(value, address & (SIZE_CART0 - 1), gbaMemory->rom);
|
||||
wait = memory->waitstates16[address >> BASE_OFFSET];
|
||||
if (memory->savedata.type == SAVEDATA_EEPROM) {
|
||||
value = GBASavedataReadEEPROM(&memory->savedata);
|
||||
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
|
||||
LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
|
||||
}
|
||||
break;
|
||||
case BASE_CART_SRAM:
|
||||
case BASE_CART_SRAM_MIRROR:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load16: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load16: 0x%08X", address);
|
||||
break;
|
||||
default:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
|
||||
value = memory->load16(memory, gbaMemory->p->cpu.currentPC + (gbaMemory->p->cpu.executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB) * 2, 0);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
|
||||
value = cpu->memory.load16(&gba->cpu, cpu->currentPC + (cpu->executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB) * 2, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -276,45 +279,46 @@ int16_t GBALoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter)
|
|||
return (value >> rotate) | (value << (16 - rotate));
|
||||
}
|
||||
|
||||
uint8_t GBALoadU8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
||||
return GBALoad8(memory, address, cycleCounter);
|
||||
uint8_t GBALoadU8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
return GBALoad8(cpu, address, cycleCounter);
|
||||
}
|
||||
|
||||
int8_t GBALoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
int8_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int8_t value = 0;
|
||||
int wait = 0;
|
||||
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_BIOS:
|
||||
if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) {
|
||||
if (cpu->currentPC >> BASE_OFFSET == REGION_BIOS) {
|
||||
if (address < SIZE_BIOS) {
|
||||
value = ((int8_t*) gbaMemory->bios)[address];
|
||||
value = ((int8_t*) memory->bios)[address];
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
} else {
|
||||
value = gbaMemory->biosPrefetch;
|
||||
value = memory->biosPrefetch;
|
||||
}
|
||||
break;
|
||||
case BASE_WORKING_RAM:
|
||||
value = ((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)];
|
||||
wait = gbaMemory->waitstates16[REGION_WORKING_RAM];
|
||||
value = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
|
||||
wait = memory->waitstates16[REGION_WORKING_RAM];
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
value = ((int8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
|
||||
value = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
|
||||
break;
|
||||
case BASE_IO:
|
||||
value = (GBAIORead(gbaMemory->p, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
|
||||
value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
|
||||
break;
|
||||
case BASE_PALETTE_RAM:
|
||||
value = ((int8_t*) gbaMemory->p->video.renderer->palette)[address & (SIZE_PALETTE_RAM - 1)];
|
||||
value = ((int8_t*) gba->video.renderer->palette)[address & (SIZE_PALETTE_RAM - 1)];
|
||||
break;
|
||||
case BASE_VRAM:
|
||||
value = ((int8_t*) gbaMemory->p->video.renderer->vram)[address & 0x0001FFFF];
|
||||
value = ((int8_t*) gba->video.renderer->vram)[address & 0x0001FFFF];
|
||||
break;
|
||||
case BASE_OAM:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address);
|
||||
break;
|
||||
case BASE_CART0:
|
||||
case BASE_CART0_EX:
|
||||
|
@ -322,26 +326,26 @@ int8_t GBALoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
|||
case BASE_CART1_EX:
|
||||
case BASE_CART2:
|
||||
case BASE_CART2_EX:
|
||||
wait = gbaMemory->waitstates16[address >> BASE_OFFSET];
|
||||
if ((address & (SIZE_CART0 - 1)) < gbaMemory->romSize) {
|
||||
value = ((int8_t*) gbaMemory->rom)[address & (SIZE_CART0 - 1)];
|
||||
wait = memory->waitstates16[address >> BASE_OFFSET];
|
||||
if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
|
||||
value = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
|
||||
}
|
||||
break;
|
||||
case BASE_CART_SRAM:
|
||||
case BASE_CART_SRAM_MIRROR:
|
||||
wait = gbaMemory->waitstates16[address >> BASE_OFFSET];
|
||||
if (gbaMemory->savedata.type == SAVEDATA_NONE) {
|
||||
GBASavedataInitSRAM(&gbaMemory->savedata);
|
||||
wait = memory->waitstates16[address >> BASE_OFFSET];
|
||||
if (memory->savedata.type == SAVEDATA_NONE) {
|
||||
GBASavedataInitSRAM(&memory->savedata);
|
||||
}
|
||||
if (gbaMemory->savedata.type == SAVEDATA_SRAM) {
|
||||
value = gbaMemory->savedata.data[address & (SIZE_CART_SRAM - 1)];
|
||||
} else if (gbaMemory->savedata.type == SAVEDATA_FLASH512 || gbaMemory->savedata.type == SAVEDATA_FLASH1M) {
|
||||
value = GBASavedataReadFlash(&gbaMemory->savedata, address);
|
||||
if (memory->savedata.type == SAVEDATA_SRAM) {
|
||||
value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
|
||||
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
|
||||
value = GBASavedataReadFlash(&memory->savedata, address);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
|
||||
value = memory->load16(memory, gbaMemory->p->cpu.currentPC + (gbaMemory->p->cpu.executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB) * 2, 0) >> ((address & 1) << 3);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
|
||||
value = cpu->memory.load16(cpu, cpu->currentPC + (cpu->executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB) * 2, 0) >> ((address & 1) << 3);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -351,45 +355,46 @@ int8_t GBALoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
|
|||
return value;
|
||||
}
|
||||
|
||||
void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value, int* cycleCounter) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int wait = 0;
|
||||
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_WORKING_RAM:
|
||||
STORE_32(value, address & (SIZE_WORKING_RAM - 1), gbaMemory->wram);
|
||||
wait = gbaMemory->waitstates32[REGION_WORKING_RAM];
|
||||
STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
|
||||
wait = memory->waitstates32[REGION_WORKING_RAM];
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
STORE_32(value, address & (SIZE_WORKING_IRAM - 1), gbaMemory->iwram);
|
||||
STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
|
||||
break;
|
||||
case BASE_IO:
|
||||
GBAIOWrite32(gbaMemory->p, address & (SIZE_IO - 1), value);
|
||||
GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
|
||||
break;
|
||||
case BASE_PALETTE_RAM:
|
||||
STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gbaMemory->p->video.palette);
|
||||
gbaMemory->p->video.renderer->writePalette(gbaMemory->p->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
|
||||
gbaMemory->p->video.renderer->writePalette(gbaMemory->p->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
|
||||
STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
|
||||
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
|
||||
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
|
||||
break;
|
||||
case BASE_VRAM:
|
||||
if ((address & OFFSET_MASK) < SIZE_VRAM - 2) {
|
||||
STORE_32(value, address & 0x0001FFFF, gbaMemory->p->video.renderer->vram);
|
||||
STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
|
||||
}
|
||||
break;
|
||||
case BASE_OAM:
|
||||
STORE_32(value, address & (SIZE_OAM - 1), gbaMemory->p->video.oam.raw);
|
||||
gbaMemory->p->video.renderer->writeOAM(gbaMemory->p->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
|
||||
gbaMemory->p->video.renderer->writeOAM(gbaMemory->p->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
|
||||
STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
|
||||
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
|
||||
gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
|
||||
break;
|
||||
case BASE_CART0:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
|
||||
break;
|
||||
case BASE_CART_SRAM:
|
||||
case BASE_CART_SRAM_MIRROR:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
|
||||
break;
|
||||
default:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -398,54 +403,55 @@ void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value, int*
|
|||
}
|
||||
}
|
||||
|
||||
void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value, int* cycleCounter) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int wait = 0;
|
||||
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_WORKING_RAM:
|
||||
STORE_16(value, address & (SIZE_WORKING_RAM - 1), gbaMemory->wram);
|
||||
wait = gbaMemory->waitstates16[REGION_WORKING_RAM];
|
||||
STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
|
||||
wait = memory->waitstates16[REGION_WORKING_RAM];
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
STORE_16(value, address & (SIZE_WORKING_IRAM - 1), gbaMemory->iwram);
|
||||
STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
|
||||
break;
|
||||
case BASE_IO:
|
||||
GBAIOWrite(gbaMemory->p, address & (SIZE_IO - 1), value);
|
||||
GBAIOWrite(gba, address & (SIZE_IO - 1), value);
|
||||
break;
|
||||
case BASE_PALETTE_RAM:
|
||||
STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gbaMemory->p->video.palette);
|
||||
gbaMemory->p->video.renderer->writePalette(gbaMemory->p->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
|
||||
STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
|
||||
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
|
||||
break;
|
||||
case BASE_VRAM:
|
||||
if ((address & OFFSET_MASK) < SIZE_VRAM) {
|
||||
STORE_16(value, address & 0x0001FFFF, gbaMemory->p->video.renderer->vram);
|
||||
STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
|
||||
}
|
||||
break;
|
||||
case BASE_OAM:
|
||||
STORE_16(value, address & (SIZE_OAM - 1), gbaMemory->p->video.oam.raw);
|
||||
gbaMemory->p->video.renderer->writeOAM(gbaMemory->p->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
|
||||
STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
|
||||
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
|
||||
break;
|
||||
case BASE_CART0:
|
||||
if (IS_GPIO_REGISTER(address & 0xFFFFFF)) {
|
||||
uint32_t reg = address & 0xFFFFFF;
|
||||
GBAGPIOWrite(&gbaMemory->gpio, reg, value);
|
||||
GBAGPIOWrite(&memory->gpio, reg, value);
|
||||
} else {
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
|
||||
}
|
||||
break;
|
||||
case BASE_CART2_EX:
|
||||
if (gbaMemory->savedata.type == SAVEDATA_NONE) {
|
||||
GBASavedataInitEEPROM(&gbaMemory->savedata);
|
||||
if (memory->savedata.type == SAVEDATA_NONE) {
|
||||
GBASavedataInitEEPROM(&memory->savedata);
|
||||
}
|
||||
GBASavedataWriteEEPROM(&gbaMemory->savedata, value, 1);
|
||||
GBASavedataWriteEEPROM(&memory->savedata, value, 1);
|
||||
break;
|
||||
case BASE_CART_SRAM:
|
||||
case BASE_CART_SRAM_MIRROR:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
|
||||
break;
|
||||
default:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -454,57 +460,58 @@ void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value, int*
|
|||
}
|
||||
}
|
||||
|
||||
void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value, int* cycleCounter) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int wait = 0;
|
||||
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_WORKING_RAM:
|
||||
((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
|
||||
wait = gbaMemory->waitstates16[REGION_WORKING_RAM];
|
||||
((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
|
||||
wait = memory->waitstates16[REGION_WORKING_RAM];
|
||||
break;
|
||||
case BASE_WORKING_IRAM:
|
||||
((int8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
|
||||
((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
|
||||
break;
|
||||
case BASE_IO:
|
||||
GBAIOWrite8(gbaMemory->p, address & (SIZE_IO - 1), value);
|
||||
GBAIOWrite8(gba, address & (SIZE_IO - 1), value);
|
||||
break;
|
||||
case BASE_PALETTE_RAM:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
|
||||
break;
|
||||
case BASE_VRAM:
|
||||
if (address >= 0x06018000) {
|
||||
// TODO: check BG mode
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
|
||||
break;
|
||||
}
|
||||
((int8_t*) gbaMemory->p->video.renderer->vram)[address & 0x1FFFE] = value;
|
||||
((int8_t*) gbaMemory->p->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
|
||||
((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value;
|
||||
((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
|
||||
break;
|
||||
case BASE_OAM:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
|
||||
break;
|
||||
case BASE_CART0:
|
||||
GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
|
||||
break;
|
||||
case BASE_CART_SRAM:
|
||||
case BASE_CART_SRAM_MIRROR:
|
||||
if (gbaMemory->savedata.type == SAVEDATA_NONE) {
|
||||
if (memory->savedata.type == SAVEDATA_NONE) {
|
||||
if (address == SAVEDATA_FLASH_BASE) {
|
||||
GBASavedataInitFlash(&gbaMemory->savedata);
|
||||
GBASavedataInitFlash(&memory->savedata);
|
||||
} else {
|
||||
GBASavedataInitSRAM(&gbaMemory->savedata);
|
||||
GBASavedataInitSRAM(&memory->savedata);
|
||||
}
|
||||
}
|
||||
if (gbaMemory->savedata.type == SAVEDATA_FLASH512 || gbaMemory->savedata.type == SAVEDATA_FLASH1M) {
|
||||
GBASavedataWriteFlash(&gbaMemory->savedata, address, value);
|
||||
} else if (gbaMemory->savedata.type == SAVEDATA_SRAM) {
|
||||
gbaMemory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
|
||||
if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
|
||||
GBASavedataWriteFlash(&memory->savedata, address, value);
|
||||
} else if (memory->savedata.type == SAVEDATA_SRAM) {
|
||||
memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
|
||||
}
|
||||
wait = gbaMemory->waitstates16[REGION_CART_SRAM];
|
||||
wait = memory->waitstates16[REGION_CART_SRAM];
|
||||
break;
|
||||
default:
|
||||
GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
|
||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -513,14 +520,16 @@ void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value, int* cy
|
|||
}
|
||||
}
|
||||
|
||||
static int GBAWaitMultiple(struct ARMMemory* memory, uint32_t startAddress, int count) {
|
||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||
int wait = 1 + gbaMemory->waitstates32[startAddress >> BASE_OFFSET];
|
||||
wait += (1 + gbaMemory->waitstatesSeq32[startAddress >> BASE_OFFSET]) * (count - 1);
|
||||
static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int wait = 1 + memory->waitstates32[startAddress >> BASE_OFFSET];
|
||||
wait += (1 + memory->waitstatesSeq32[startAddress >> BASE_OFFSET]) * (count - 1);
|
||||
return wait;
|
||||
}
|
||||
|
||||
void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) {
|
||||
void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int sram = parameters & 0x0003;
|
||||
int ws0 = (parameters & 0x000C) >> 2;
|
||||
int ws0seq = (parameters & 0x0010) >> 4;
|
||||
|
@ -569,48 +578,52 @@ void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) {
|
|||
memory->waitstatesPrefetch32[REGION_CART2] = memory->waitstatesPrefetch32[REGION_CART2_EX] = 0;
|
||||
}
|
||||
|
||||
memory->d.activePrefetchCycles32 = memory->waitstatesPrefetch32[memory->activeRegion];
|
||||
memory->d.activePrefetchCycles16 = memory->waitstatesPrefetch16[memory->activeRegion];
|
||||
memory->d.activeNonseqCycles32 = memory->waitstates32[memory->activeRegion];
|
||||
memory->d.activeNonseqCycles16 = memory->waitstates16[memory->activeRegion];
|
||||
gba->cpu.memory.activePrefetchCycles32 = memory->waitstatesPrefetch32[memory->activeRegion];
|
||||
gba->cpu.memory.activePrefetchCycles16 = memory->waitstatesPrefetch16[memory->activeRegion];
|
||||
gba->cpu.memory.activeNonseqCycles32 = memory->waitstates32[memory->activeRegion];
|
||||
gba->cpu.memory.activeNonseqCycles16 = memory->waitstates16[memory->activeRegion];
|
||||
}
|
||||
|
||||
void GBAMemoryWriteDMASAD(struct GBAMemory* memory, int dma, uint32_t address) {
|
||||
void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
memory->dma[dma].source = address & 0xFFFFFFFE;
|
||||
}
|
||||
|
||||
void GBAMemoryWriteDMADAD(struct GBAMemory* memory, int dma, uint32_t address) {
|
||||
void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
memory->dma[dma].dest = address & 0xFFFFFFFE;
|
||||
}
|
||||
|
||||
void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count) {
|
||||
void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
|
||||
}
|
||||
|
||||
uint16_t GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control) {
|
||||
uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
struct GBADMA* currentDma = &memory->dma[dma];
|
||||
int wasEnabled = currentDma->enable;
|
||||
currentDma->packed = control;
|
||||
|
||||
if (currentDma->drq) {
|
||||
GBALog(memory->p, GBA_LOG_STUB, "DRQ not implemented");
|
||||
GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
|
||||
}
|
||||
|
||||
if (!wasEnabled && currentDma->enable) {
|
||||
currentDma->nextSource = currentDma->source;
|
||||
currentDma->nextDest = currentDma->dest;
|
||||
currentDma->nextCount = currentDma->count;
|
||||
GBAMemoryScheduleDMA(memory, dma, currentDma);
|
||||
GBAMemoryScheduleDMA(gba, dma, currentDma);
|
||||
}
|
||||
// If the DMA has already occurred, this value might have changed since the function started
|
||||
return currentDma->packed;
|
||||
};
|
||||
|
||||
void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info) {
|
||||
void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
|
||||
switch (info->timing) {
|
||||
case DMA_TIMING_NOW:
|
||||
info->nextEvent = memory->p->cpu.cycles;
|
||||
GBAMemoryUpdateDMAs(memory, 0);
|
||||
info->nextEvent = gba->cpu.cycles;
|
||||
GBAMemoryUpdateDMAs(gba, 0);
|
||||
break;
|
||||
case DMA_TIMING_HBLANK:
|
||||
// Handled implicitly
|
||||
|
@ -624,11 +637,11 @@ void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* i
|
|||
info->nextEvent = INT_MAX;
|
||||
switch (number) {
|
||||
case 0:
|
||||
GBALog(memory->p, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
|
||||
GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
GBAAudioScheduleFifoDma(&memory->p->audio, number, info);
|
||||
GBAAudioScheduleFifoDma(&gba->audio, number, info);
|
||||
break;
|
||||
case 3:
|
||||
// GBAVideoScheduleVCaptureDma(dma, info);
|
||||
|
@ -637,7 +650,8 @@ void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* i
|
|||
}
|
||||
}
|
||||
|
||||
void GBAMemoryRunHblankDMAs(struct GBAMemory* memory, int32_t cycles) {
|
||||
void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
struct GBADMA* dma;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
|
@ -646,10 +660,11 @@ void GBAMemoryRunHblankDMAs(struct GBAMemory* memory, int32_t cycles) {
|
|||
dma->nextEvent = cycles;
|
||||
}
|
||||
}
|
||||
GBAMemoryUpdateDMAs(memory, 0);
|
||||
GBAMemoryUpdateDMAs(gba, 0);
|
||||
}
|
||||
|
||||
void GBAMemoryRunVblankDMAs(struct GBAMemory* memory, int32_t cycles) {
|
||||
void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
struct GBADMA* dma;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
|
@ -658,10 +673,11 @@ void GBAMemoryRunVblankDMAs(struct GBAMemory* memory, int32_t cycles) {
|
|||
dma->nextEvent = cycles;
|
||||
}
|
||||
}
|
||||
GBAMemoryUpdateDMAs(memory, 0);
|
||||
GBAMemoryUpdateDMAs(gba, 0);
|
||||
}
|
||||
|
||||
int32_t GBAMemoryRunDMAs(struct GBAMemory* memory, int32_t cycles) {
|
||||
int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
if (memory->nextDMA == INT_MAX) {
|
||||
return INT_MAX;
|
||||
}
|
||||
|
@ -669,15 +685,16 @@ int32_t GBAMemoryRunDMAs(struct GBAMemory* memory, int32_t cycles) {
|
|||
memory->eventDiff += cycles;
|
||||
if (memory->nextDMA <= 0) {
|
||||
struct GBADMA* dma = &memory->dma[memory->activeDMA];
|
||||
GBAMemoryServiceDMA(memory, memory->activeDMA, dma);
|
||||
GBAMemoryUpdateDMAs(memory, memory->eventDiff);
|
||||
GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
|
||||
GBAMemoryUpdateDMAs(gba, memory->eventDiff);
|
||||
memory->eventDiff = 0;
|
||||
}
|
||||
return memory->nextDMA;
|
||||
}
|
||||
|
||||
void GBAMemoryUpdateDMAs(struct GBAMemory* memory, int32_t cycles) {
|
||||
void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
|
||||
int i;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
memory->activeDMA = -1;
|
||||
memory->nextDMA = INT_MAX;
|
||||
for (i = 3; i >= 0; --i) {
|
||||
|
@ -690,12 +707,13 @@ void GBAMemoryUpdateDMAs(struct GBAMemory* memory, int32_t cycles) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (memory->nextDMA < memory->p->cpu.nextEvent) {
|
||||
memory->p->cpu.nextEvent = memory->nextDMA;
|
||||
if (memory->nextDMA < gba->cpu.nextEvent) {
|
||||
gba->cpu.nextEvent = memory->nextDMA;
|
||||
}
|
||||
}
|
||||
|
||||
void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* info) {
|
||||
void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
uint32_t width = info->width ? 4 : 2;
|
||||
int sourceOffset = DMA_OFFSET[info->srcControl] * width;
|
||||
int destOffset = DMA_OFFSET[info->dstControl] * width;
|
||||
|
@ -726,8 +744,8 @@ void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* in
|
|||
|
||||
if (width == 4) {
|
||||
int32_t word;
|
||||
word = memory->d.load32(&memory->d, source, 0);
|
||||
memory->d.store32(&memory->d, dest, word, 0);
|
||||
word = gba->cpu.memory.load32(&gba->cpu, source, 0);
|
||||
gba->cpu.memory.store32(&gba->cpu, dest, word, 0);
|
||||
source += sourceOffset;
|
||||
dest += destOffset;
|
||||
--wordsRemaining;
|
||||
|
@ -735,7 +753,7 @@ void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* in
|
|||
uint16_t word;
|
||||
if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
|
||||
word = GBASavedataReadEEPROM(&memory->savedata);
|
||||
memory->d.store16(&memory->d, dest, word, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, dest, word, 0);
|
||||
source += sourceOffset;
|
||||
dest += destOffset;
|
||||
--wordsRemaining;
|
||||
|
@ -743,14 +761,14 @@ void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* in
|
|||
if (memory->savedata.type == SAVEDATA_NONE) {
|
||||
GBASavedataInitEEPROM(&memory->savedata);
|
||||
}
|
||||
word = memory->d.load16(&memory->d, source, 0);
|
||||
word = gba->cpu.memory.load16(&gba->cpu, source, 0);
|
||||
GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
|
||||
source += sourceOffset;
|
||||
dest += destOffset;
|
||||
--wordsRemaining;
|
||||
} else {
|
||||
word = memory->d.load16(&memory->d, source, 0);
|
||||
memory->d.store16(&memory->d, dest, word, 0);
|
||||
word = gba->cpu.memory.load16(&gba->cpu, source, 0);
|
||||
gba->cpu.memory.store16(&gba->cpu, dest, word, 0);
|
||||
source += sourceOffset;
|
||||
dest += destOffset;
|
||||
--wordsRemaining;
|
||||
|
@ -769,10 +787,10 @@ void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* in
|
|||
if (info->dstControl == DMA_INCREMENT_RELOAD) {
|
||||
info->nextDest = info->dest;
|
||||
}
|
||||
GBAMemoryScheduleDMA(memory, number, info);
|
||||
GBAMemoryScheduleDMA(gba, number, info);
|
||||
}
|
||||
if (info->doIrq) {
|
||||
GBARaiseIRQ(memory->p, IRQ_DMA0 + number);
|
||||
GBARaiseIRQ(gba, IRQ_DMA0 + number);
|
||||
}
|
||||
} else {
|
||||
info->nextDest = dest;
|
||||
|
@ -786,7 +804,7 @@ void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* in
|
|||
memory->dma[i].nextEvent += cycles;
|
||||
}
|
||||
}
|
||||
memory->p->cpu.cycles += cycles;
|
||||
gba->cpu.cycles += cycles;
|
||||
}
|
||||
|
||||
void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state) {
|
||||
|
|
|
@ -106,9 +106,6 @@ struct GBADMA {
|
|||
};
|
||||
|
||||
struct GBAMemory {
|
||||
struct ARMMemory d;
|
||||
struct GBA* p;
|
||||
|
||||
uint32_t* bios;
|
||||
uint32_t* wram;
|
||||
uint32_t* iwram;
|
||||
|
@ -136,28 +133,31 @@ struct GBAMemory {
|
|||
int32_t eventDiff;
|
||||
};
|
||||
|
||||
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter);
|
||||
int16_t GBALoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter);
|
||||
uint16_t GBALoadU16(struct ARMMemory* memory, uint32_t address, int* cycleCounter);
|
||||
int8_t GBALoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter);
|
||||
uint8_t GBALoadU8(struct ARMMemory* memory, uint32_t address, int* cycleCounter);
|
||||
void GBAMemoryInit(struct GBA* gba);
|
||||
void GBAMemoryDeinit(struct GBA* gba);
|
||||
|
||||
void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value, int* cycleCounter);
|
||||
void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value, int* cycleCounter);
|
||||
void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value, int* cycleCounter);
|
||||
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);
|
||||
|
||||
void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters);
|
||||
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);
|
||||
void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter);
|
||||
|
||||
void GBAMemoryWriteDMASAD(struct GBAMemory* memory, int dma, uint32_t address);
|
||||
void GBAMemoryWriteDMADAD(struct GBAMemory* memory, int dma, uint32_t address);
|
||||
void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count);
|
||||
uint16_t GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control);
|
||||
void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters);
|
||||
|
||||
void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info);
|
||||
void GBAMemoryRunHblankDMAs(struct GBAMemory* memory, int32_t cycles);
|
||||
void GBAMemoryRunVblankDMAs(struct GBAMemory* memory, int32_t cycles);
|
||||
void GBAMemoryUpdateDMAs(struct GBAMemory* memory, int32_t cycles);
|
||||
int32_t GBAMemoryRunDMAs(struct GBAMemory* memory, int32_t cycles);
|
||||
void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address);
|
||||
void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address);
|
||||
void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count);
|
||||
uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control);
|
||||
|
||||
void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info);
|
||||
void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles);
|
||||
void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles);
|
||||
void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles);
|
||||
int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles);
|
||||
|
||||
struct GBASerializedState;
|
||||
void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state);
|
||||
|
|
|
@ -52,7 +52,7 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
memcpy(gba->cpu.bankedSPSRs, state->cpu.bankedSPSRs, 6 * sizeof(int32_t));
|
||||
gba->cpu.executionMode = gba->cpu.cpsr.t ? MODE_THUMB : MODE_ARM;
|
||||
gba->cpu.privilegeMode = gba->cpu.cpsr.priv;
|
||||
gba->cpu.memory->setActiveRegion(gba->cpu.memory, gba->cpu.gprs[ARM_PC]);
|
||||
gba->cpu.memory.setActiveRegion(&gba->cpu, gba->cpu.gprs[ARM_PC]);
|
||||
|
||||
GBAMemoryDeserialize(&gba->memory, state);
|
||||
GBAIODeserialize(gba, state);
|
||||
|
|
|
@ -90,7 +90,7 @@ int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) {
|
|||
video->renderer->finishFrame(video->renderer);
|
||||
}
|
||||
video->nextVblankIRQ = video->nextEvent + VIDEO_TOTAL_LENGTH;
|
||||
GBAMemoryRunVblankDMAs(&video->p->memory, lastEvent);
|
||||
GBAMemoryRunVblankDMAs(video->p, lastEvent);
|
||||
if (video->vblankIRQ) {
|
||||
GBARaiseIRQ(video->p, IRQ_VBLANK);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) {
|
|||
video->nextHblankIRQ = video->nextHblank;
|
||||
|
||||
if (video->vcount < VIDEO_VERTICAL_PIXELS) {
|
||||
GBAMemoryRunHblankDMAs(&video->p->memory, lastEvent);
|
||||
GBAMemoryRunHblankDMAs(video->p, lastEvent);
|
||||
}
|
||||
if (video->hblankIRQ) {
|
||||
GBARaiseIRQ(video->p, IRQ_HBLANK);
|
||||
|
@ -207,10 +207,10 @@ void GBAVideoDeserialize(struct GBAVideo* video, struct GBASerializedState* stat
|
|||
memcpy(video->renderer->vram, state->vram, SIZE_VRAM);
|
||||
int i;
|
||||
for (i = 0; i < SIZE_OAM; i += 2) {
|
||||
GBAStore16(&video->p->memory.d, BASE_OAM | i, state->oam[i >> 1], 0);
|
||||
GBAStore16(&video->p->cpu, BASE_OAM | i, state->oam[i >> 1], 0);
|
||||
}
|
||||
for (i = 0; i < SIZE_PALETTE_RAM; i += 2) {
|
||||
GBAStore16(&video->p->memory.d, BASE_PALETTE_RAM | i, state->pram[i >> 1], 0);
|
||||
GBAStore16(&video->p->cpu, BASE_PALETTE_RAM | i, state->pram[i >> 1], 0);
|
||||
}
|
||||
union GBARegisterDISPSTAT dispstat;
|
||||
dispstat.packed = state->io[REG_DISPSTAT >> 1];
|
||||
|
|
103
src/gba/gba.c
103
src/gba/gba.c
|
@ -91,10 +91,10 @@ static const struct GBACartridgeOverride _overrides[] = {
|
|||
{ { 0, 0, 0, 0 }, 0, 0 }
|
||||
};
|
||||
|
||||
static void GBAProcessEvents(struct ARMBoard* board);
|
||||
static void GBAProcessEvents(struct ARMCore* cpu);
|
||||
static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles);
|
||||
static void GBAHitStub(struct ARMBoard* board, uint32_t opcode);
|
||||
static void GBAIllegal(struct ARMBoard* board, uint32_t opcode);
|
||||
static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode);
|
||||
static void GBAIllegal(struct ARMCore* cpu, uint32_t opcode);
|
||||
|
||||
static void _checkOverrides(struct GBA* gba, uint32_t code);
|
||||
|
||||
|
@ -104,13 +104,8 @@ void GBAInit(struct GBA* gba) {
|
|||
|
||||
ARMInit(&gba->cpu);
|
||||
|
||||
gba->memory.p = gba;
|
||||
GBAMemoryInit(&gba->memory);
|
||||
ARMAssociateMemory(&gba->cpu, &gba->memory.d);
|
||||
|
||||
gba->board.p = gba;
|
||||
GBABoardInit(&gba->board);
|
||||
ARMAssociateBoard(&gba->cpu, &gba->board.d);
|
||||
GBAMemoryInit(gba);
|
||||
GBABoardInit(&gba->cpu.board);
|
||||
|
||||
gba->video.p = gba;
|
||||
GBAVideoInit(&gba->video);
|
||||
|
@ -139,23 +134,22 @@ void GBAInit(struct GBA* gba) {
|
|||
}
|
||||
|
||||
void GBADeinit(struct GBA* gba) {
|
||||
GBAMemoryDeinit(&gba->memory);
|
||||
GBAMemoryDeinit(gba);
|
||||
GBAVideoDeinit(&gba->video);
|
||||
GBAAudioDeinit(&gba->audio);
|
||||
}
|
||||
|
||||
void GBABoardInit(struct GBABoard* board) {
|
||||
board->d.reset = GBABoardReset;
|
||||
board->d.processEvents = GBAProcessEvents;
|
||||
board->d.swi16 = GBASwi16;
|
||||
board->d.swi32 = GBASwi32;
|
||||
board->d.hitIllegal = GBAIllegal;
|
||||
board->d.readCPSR = GBATestIRQ;
|
||||
board->d.hitStub = GBAHitStub;
|
||||
void GBABoardInit(struct ARMBoard* board) {
|
||||
board->reset = GBABoardReset;
|
||||
board->processEvents = GBAProcessEvents;
|
||||
board->swi16 = GBASwi16;
|
||||
board->swi32 = GBASwi32;
|
||||
board->hitIllegal = GBAIllegal;
|
||||
board->readCPSR = GBATestIRQ;
|
||||
board->hitStub = GBAHitStub;
|
||||
}
|
||||
|
||||
void GBABoardReset(struct ARMBoard* board) {
|
||||
struct ARMCore* cpu = board->cpu;
|
||||
void GBABoardReset(struct ARMCore* cpu) {
|
||||
ARMSetPrivilegeMode(cpu, MODE_IRQ);
|
||||
cpu->gprs[ARM_SP] = SP_BASE_IRQ;
|
||||
ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
|
||||
|
@ -164,50 +158,50 @@ void GBABoardReset(struct ARMBoard* board) {
|
|||
cpu->gprs[ARM_SP] = SP_BASE_SYSTEM;
|
||||
}
|
||||
|
||||
static void GBAProcessEvents(struct ARMBoard* board) {
|
||||
static void GBAProcessEvents(struct ARMCore* cpu) {
|
||||
do {
|
||||
struct GBABoard* gbaBoard = (struct GBABoard*) board;
|
||||
int32_t cycles = board->cpu->cycles;
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
int32_t cycles = cpu->cycles;
|
||||
int32_t nextEvent = INT_MAX;
|
||||
int32_t testEvent;
|
||||
|
||||
if (gbaBoard->p->springIRQ) {
|
||||
ARMRaiseIRQ(&gbaBoard->p->cpu);
|
||||
gbaBoard->p->springIRQ = 0;
|
||||
if (gba->springIRQ) {
|
||||
ARMRaiseIRQ(cpu);
|
||||
gba->springIRQ = 0;
|
||||
}
|
||||
|
||||
testEvent = GBAVideoProcessEvents(&gbaBoard->p->video, cycles);
|
||||
testEvent = GBAVideoProcessEvents(&gba->video, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
testEvent = GBAAudioProcessEvents(&gbaBoard->p->audio, cycles);
|
||||
testEvent = GBAAudioProcessEvents(&gba->audio, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
testEvent = GBATimersProcessEvents(gbaBoard->p, cycles);
|
||||
testEvent = GBATimersProcessEvents(gba, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
testEvent = GBAMemoryRunDMAs(&gbaBoard->p->memory, cycles);
|
||||
testEvent = GBAMemoryRunDMAs(gba, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
testEvent = GBASIOProcessEvents(&gbaBoard->p->sio, cycles);
|
||||
testEvent = GBASIOProcessEvents(&gba->sio, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
board->cpu->cycles -= cycles;
|
||||
board->cpu->nextEvent = nextEvent;
|
||||
cpu->cycles -= cycles;
|
||||
cpu->nextEvent = nextEvent;
|
||||
|
||||
if (board->cpu->halted) {
|
||||
board->cpu->cycles = board->cpu->nextEvent;
|
||||
if (cpu->halted) {
|
||||
cpu->cycles = cpu->nextEvent;
|
||||
}
|
||||
} while (board->cpu->cycles >= board->cpu->nextEvent);
|
||||
} while (cpu->cycles >= cpu->nextEvent);
|
||||
}
|
||||
|
||||
static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles) {
|
||||
|
@ -389,7 +383,7 @@ void GBALoadBIOS(struct GBA* gba, int fd) {
|
|||
}
|
||||
gba->biosChecksum = checksum;
|
||||
if ((gba->cpu.gprs[ARM_PC] >> BASE_OFFSET) == BASE_BIOS) {
|
||||
gba->memory.d.setActiveRegion(&gba->memory.d, gba->cpu.gprs[ARM_PC]);
|
||||
gba->cpu.memory.setActiveRegion(&gba->cpu, gba->cpu.gprs[ARM_PC]);
|
||||
}
|
||||
// TODO: error check
|
||||
}
|
||||
|
@ -482,9 +476,8 @@ void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq) {
|
|||
}
|
||||
}
|
||||
|
||||
void GBATestIRQ(struct ARMBoard* board) {
|
||||
struct GBABoard* gbaBoard = (struct GBABoard*) board;
|
||||
struct GBA* gba = gbaBoard->p;
|
||||
void GBATestIRQ(struct ARMCore* cpu) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
if (gba->memory.io[REG_IME >> 1] && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
|
||||
gba->springIRQ = 1;
|
||||
gba->cpu.nextEvent = 0;
|
||||
|
@ -529,9 +522,9 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {
|
|||
}
|
||||
|
||||
void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel level, const char* format, ...) {
|
||||
struct GBABoard* gbaBoard = 0;
|
||||
if (debugger->cpu && debugger->cpu->board) {
|
||||
gbaBoard = (struct GBABoard*) debugger->cpu->board;
|
||||
struct GBA* gba = 0;
|
||||
if (debugger->cpu) {
|
||||
gba = (struct GBA*) debugger->cpu;
|
||||
}
|
||||
|
||||
enum GBALogLevel gbaLevel;
|
||||
|
@ -551,26 +544,26 @@ void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel leve
|
|||
}
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
_GBAVLog(gbaBoard ? gbaBoard->p : 0, gbaLevel, format, args);
|
||||
_GBAVLog(gba, gbaLevel, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
|
||||
struct GBABoard* gbaBoard = (struct GBABoard*) board;
|
||||
void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
enum GBALogLevel level = GBA_LOG_FATAL;
|
||||
if (gbaBoard->p->debugger) {
|
||||
if (gba->debugger) {
|
||||
level = GBA_LOG_STUB;
|
||||
ARMDebuggerEnter(gbaBoard->p->debugger, DEBUGGER_ENTER_ILLEGAL_OP);
|
||||
ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP);
|
||||
}
|
||||
GBALog(gbaBoard->p, level, "Stub opcode: %08x", opcode);
|
||||
GBALog(gba, level, "Stub opcode: %08x", opcode);
|
||||
}
|
||||
|
||||
void GBAIllegal(struct ARMBoard* board, uint32_t opcode) {
|
||||
struct GBABoard* gbaBoard = (struct GBABoard*) board;
|
||||
GBALog(gbaBoard->p, GBA_LOG_WARN, "Illegal opcode: %08x", opcode);
|
||||
if (gbaBoard->p->debugger) {
|
||||
ARMDebuggerEnter(gbaBoard->p->debugger, DEBUGGER_ENTER_ILLEGAL_OP);
|
||||
void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) {
|
||||
struct GBA* gba = (struct GBA*) cpu;
|
||||
GBALog(gba, GBA_LOG_WARN, "Illegal opcode: %08x", opcode);
|
||||
if (gba->debugger) {
|
||||
ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,14 +64,8 @@ struct GBARotationSource;
|
|||
struct GBA;
|
||||
typedef void (*GBALogHandler)(struct GBA*, enum GBALogLevel, const char* format, va_list args);
|
||||
|
||||
struct GBABoard {
|
||||
struct ARMBoard d;
|
||||
struct GBA* p;
|
||||
};
|
||||
|
||||
struct GBA {
|
||||
struct ARMCore cpu;
|
||||
struct GBABoard board;
|
||||
struct GBAMemory memory;
|
||||
struct GBAVideo video;
|
||||
struct GBAAudio audio;
|
||||
|
@ -125,11 +119,8 @@ struct GBACartridge {
|
|||
void GBAInit(struct GBA* gba);
|
||||
void GBADeinit(struct GBA* gba);
|
||||
|
||||
void GBAMemoryInit(struct GBAMemory* memory);
|
||||
void GBAMemoryDeinit(struct GBAMemory* memory);
|
||||
|
||||
void GBABoardInit(struct GBABoard* board);
|
||||
void GBABoardReset(struct ARMBoard* board);
|
||||
void GBABoardInit(struct ARMBoard* board);
|
||||
void GBABoardReset(struct ARMCore* cpu);
|
||||
|
||||
void GBATimerUpdateRegister(struct GBA* gba, int timer);
|
||||
void GBATimerWriteTMCNT_LO(struct GBA* gba, int timer, uint16_t value);
|
||||
|
@ -138,7 +129,7 @@ void GBATimerWriteTMCNT_HI(struct GBA* gba, int timer, uint16_t value);
|
|||
void GBAWriteIE(struct GBA* gba, uint16_t value);
|
||||
void GBAWriteIME(struct GBA* gba, uint16_t value);
|
||||
void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq);
|
||||
void GBATestIRQ(struct ARMBoard* board);
|
||||
void GBATestIRQ(struct ARMCore* cpu);
|
||||
void GBAHalt(struct GBA* gba);
|
||||
|
||||
void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger);
|
||||
|
|
Loading…
Reference in New Issue