diff --git a/src/arm/arm.h b/src/arm/arm.h index 4e179104c..d5bf943d5 100644 --- a/src/arm/arm.h +++ b/src/arm/arm.h @@ -82,6 +82,7 @@ struct ARMMemory { 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 @@ struct ARMCore { struct ARMMemory* memory; struct ARMBoard* board; + + int64_t absoluteCycles; + int32_t lastCycles; }; void ARMInit(struct ARMCore* cpu); diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index 5a9d85b7d..d01759965 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -504,6 +504,7 @@ void ARMStep(struct ARMCore* cpu) { if (m & 1) { \ BODY; \ addr += 4; \ + total += 1; \ } \ } @@ -512,6 +513,7 @@ void ARMStep(struct ARMCore* cpu) { if (rs & m) { \ BODY; \ addr -= 4; \ + total += 1; \ } \ } @@ -521,11 +523,13 @@ void ARMStep(struct ARMCore* cpu) { 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 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT, 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; }) diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index 5f8b4cf8a..e1ce6eaa2 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -347,14 +347,17 @@ DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, cpu->memory->store16(cpu->memory, c 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) \ diff --git a/src/gba/gba-memory.c b/src/gba/gba-memory.c index 1a7304889..3ddb78582 100644 --- a/src/gba/gba-memory.c +++ b/src/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 @@ void GBAMemoryInit(struct GBAMemory* memory) { memory->d.setActiveRegion = GBASetActiveRegion; memory->d.activePrefetchCycles32 = 0; memory->d.activePrefetchCycles16 = 0; + memory->d.waitMultiple = GBAWaitMultiple; } void GBAMemoryDeinit(struct GBAMemory* memory) { @@ -414,6 +416,13 @@ 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); + return wait; +} + void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) { int sram = parameters & 0x0003; int ws0 = (parameters & 0x000C) >> 2;