all repos — mgba @ 05ef05317c2cb639e41648ddc74256b7977972eb

mGBA Game Boy Advance Emulator

GB: Optimize cpuLoad8
Jeffrey Pfau jeffrey@endrift.com
Mon, 22 Feb 2016 21:39:05 -0800
commit

05ef05317c2cb639e41648ddc74256b7977972eb

parent

3b24e94018c2f26f503db72b058444882fff4ccf

3 files changed, 37 insertions(+), 3 deletions(-)

jump to
M src/gb/memory.csrc/gb/memory.c

@@ -33,8 +33,40 @@ static void _GBMBC7(struct GBMemory*, uint16_t address, uint8_t value);

static uint8_t _GBMBC7Read(struct GBMemory*, uint16_t address); static void _GBMBC7Write(struct GBMemory*, uint16_t address, uint8_t value); +static uint8_t GBFastLoad8(struct LR35902Core* cpu, uint16_t address) { + if (UNLIKELY(address > cpu->memory.activeRegionEnd)) { + cpu->memory.setActiveRegion(cpu, address); + return cpu->memory.cpuLoad8(cpu, address); + } + return cpu->memory.activeRegion[address & cpu->memory.activeMask]; +} + static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) { - // TODO + struct GB* gb = (struct GB*) cpu->master; + struct GBMemory* memory = &gb->memory; + switch (address >> 12) { + case GB_REGION_CART_BANK0: + case GB_REGION_CART_BANK0 + 1: + case GB_REGION_CART_BANK0 + 2: + case GB_REGION_CART_BANK0 + 3: + cpu->memory.cpuLoad8 = GBFastLoad8; + cpu->memory.activeRegion = memory->rom; + cpu->memory.activeRegionEnd = GB_BASE_CART_BANK1; + cpu->memory.activeMask = GB_SIZE_CART_BANK0 - 1; + break; + case GB_REGION_CART_BANK1: + case GB_REGION_CART_BANK1 + 1: + case GB_REGION_CART_BANK1 + 2: + case GB_REGION_CART_BANK1 + 3: + cpu->memory.cpuLoad8 = GBFastLoad8; + cpu->memory.activeRegion = memory->romBank; + cpu->memory.activeRegionEnd = GB_BASE_VRAM; + cpu->memory.activeMask = GB_SIZE_CART_BANK0 - 1; + break; + default: + cpu->memory.cpuLoad8 = GBLoad8; + break; + } } static void _GBMemoryDMAService(struct GB* gb);

@@ -235,6 +267,7 @@ case GB_REGION_CART_BANK1 + 1:

case GB_REGION_CART_BANK1 + 2: case GB_REGION_CART_BANK1 + 3: memory->mbc(memory, address, value); + cpu->memory.setActiveRegion(cpu, cpu->pc); return; case GB_REGION_VRAM: case GB_REGION_VRAM + 1:

@@ -304,6 +337,7 @@ return;

} gb->cpu->memory.store8 = GBDMAStore8; gb->cpu->memory.load8 = GBDMALoad8; + gb->cpu->memory.cpuLoad8 = GBDMALoad8; gb->memory.dmaNext = gb->cpu->cycles + 8; if (gb->memory.dmaNext < gb->cpu->nextEvent) { gb->cpu->nextEvent = gb->memory.dmaNext;
M src/lr35902/lr35902.csrc/lr35902/lr35902.c

@@ -129,7 +129,7 @@ case LR35902_CORE_MEMORY_STORE:

cpu->memory.store8(cpu, cpu->index, cpu->bus); break; case LR35902_CORE_READ_PC: - cpu->bus = cpu->memory.load8(cpu, cpu->pc); + cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc); ++cpu->pc; break; case LR35902_CORE_STALL:
M src/lr35902/lr35902.hsrc/lr35902/lr35902.h

@@ -47,7 +47,6 @@ LR35902_CORE_READ_PC = 15,

LR35902_CORE_STALL = 19, LR35902_CORE_OP2 = 23 }; - struct LR35902Memory { uint8_t (*cpuLoad8)(struct LR35902Core*, uint16_t address); uint8_t (*load8)(struct LR35902Core*, uint16_t address);

@@ -55,6 +54,7 @@ void (*store8)(struct LR35902Core*, uint16_t address, int8_t value);

uint8_t* activeRegion; uint16_t activeMask; + uint16_t activeRegionEnd; void (*setActiveRegion)(struct LR35902Core*, uint16_t address); };