GB: Optimize cpuLoad8
Jeffrey Pfau jeffrey@endrift.com
Mon, 22 Feb 2016 21:39:05 -0800
3 files changed,
37 insertions(+),
3 deletions(-)
M
src/gb/memory.c
→
src/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.c
→
src/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.h
→
src/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); };