all repos — mgba @ b6361cdfa942d2bdc0f759eebceb4227efe991cd

mGBA Game Boy Advance Emulator

Start LDM/STM timings
Jeffrey Pfau jeffrey@endrift.com
Sat, 11 May 2013 17:05:57 -0700
commit

b6361cdfa942d2bdc0f759eebceb4227efe991cd

parent

0a37300bcf05385da830c45c57e2bfc5e41d2a6b

4 files changed, 21 insertions(+), 0 deletions(-)

jump to
M src/arm/arm.hsrc/arm/arm.h

@@ -82,6 +82,7 @@ uint32_t activeMask;

uint32_t activePrefetchCycles32; uint32_t activePrefetchCycles16; void (*setActiveRegion)(struct ARMMemory*, uint32_t address); + int (*waitMultiple)(struct ARMMemory*, uint32_t startAddress, int count); }; struct ARMBoard {

@@ -113,6 +114,9 @@ enum PrivilegeMode privilegeMode;

struct ARMMemory* memory; struct ARMBoard* board; + + int64_t absoluteCycles; + int32_t lastCycles; }; void ARMInit(struct ARMCore* cpu);
M src/arm/isa-arm.csrc/arm/isa-arm.c

@@ -504,6 +504,7 @@ for (m = rs, i = 0; m; m >>= 1, ++i) { \

if (m & 1) { \ BODY; \ addr += 4; \ + total += 1; \ } \ }

@@ -512,6 +513,7 @@ for (m = 0x8000, i = 15; m; m >>= 1, --i) { \

if (rs & m) { \ BODY; \ addr -= 4; \ + total += 1; \ } \ }

@@ -521,11 +523,13 @@ int rn = (opcode >> 16) & 0xF; \

int rs = opcode & 0x0000FFFF; \ int m; \ int i; \ + int total = 0; \ ADDRESS; \ S_PRE; \ LOOP(BODY); \ S_POST; \ WRITEBACK; \ + cpu->cycles += cpu->memory->waitMultiple(cpu->memory, addr, total); \ POST_BODY;)

@@ -681,6 +685,7 @@ ARMSetPrivilegeMode(cpu, priv);)

DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, cpu->gprs[i] = cpu->memory->load32(cpu->memory, addr, 0);, + ++cpu->cycles; if (rs & 0x8000) { ARM_WRITE_PC; })
M src/arm/isa-thumb.csrc/arm/isa-thumb.c

@@ -347,14 +347,17 @@ int rs = opcode & 0xFF; \

int32_t address = ADDRESS; \ int m; \ int i; \ + int total = 0; \ PRE_BODY; \ for LOOP { \ if (rs & m) { \ BODY; \ address OP 4; \ + ++total; \ } \ } \ POST_BODY; \ + cpu->cycles += cpu->memory->waitMultiple(cpu->memory, address, total); \ WRITEBACK;) #define DEFINE_LOAD_STORE_MULTIPLE_THUMB(NAME, BODY, WRITEBACK) \
M src/gba/gba-memory.csrc/gba/gba-memory.c

@@ -10,6 +10,7 @@

static const char* GBA_CANNOT_MMAP = "Could not map memory"; static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region); +static int GBAWaitMultiple(struct ARMMemory* memory, uint32_t startAddress, int count); 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, 4, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };

@@ -68,6 +69,7 @@ memory->d.activeMask = 0;

memory->d.setActiveRegion = GBASetActiveRegion; memory->d.activePrefetchCycles32 = 0; memory->d.activePrefetchCycles16 = 0; + memory->d.waitMultiple = GBAWaitMultiple; } void GBAMemoryDeinit(struct GBAMemory* memory) {

@@ -412,6 +414,13 @@

if (cycleCounter) { *cycleCounter += 1 + wait; } +} + +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); + return wait; } void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) {