Minor ROM access optimization
This commit is contained in:
parent
027e27caa4
commit
d3abd2dc63
@ -76,6 +76,10 @@ struct ARMMemory {
|
|||||||
void (*store32)(struct ARMMemory*, uint32_t address, int32_t value);
|
void (*store32)(struct ARMMemory*, uint32_t address, int32_t value);
|
||||||
void (*store16)(struct ARMMemory*, uint32_t address, int16_t value);
|
void (*store16)(struct ARMMemory*, uint32_t address, int16_t value);
|
||||||
void (*store8)(struct ARMMemory*, uint32_t address, int8_t value);
|
void (*store8)(struct ARMMemory*, uint32_t address, int8_t value);
|
||||||
|
|
||||||
|
uint32_t* activeRegion;
|
||||||
|
uint32_t activeMask;
|
||||||
|
void (*setActiveRegion)(struct ARMMemory*, uint32_t address);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ARMBoard {
|
struct ARMBoard {
|
||||||
|
38
src/gba.c
38
src/gba.c
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
static const char* GBA_CANNOT_MMAP = "Could not map memory";
|
static const char* GBA_CANNOT_MMAP = "Could not map memory";
|
||||||
|
|
||||||
|
static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region);
|
||||||
|
|
||||||
void GBAInit(struct GBA* gba) {
|
void GBAInit(struct GBA* gba) {
|
||||||
gba->errno = GBA_NO_ERROR;
|
gba->errno = GBA_NO_ERROR;
|
||||||
gba->errstr = 0;
|
gba->errstr = 0;
|
||||||
@ -45,6 +47,10 @@ void GBAMemoryInit(struct GBAMemory* memory) {
|
|||||||
memory->p->errno = GBA_OUT_OF_MEMORY;
|
memory->p->errno = GBA_OUT_OF_MEMORY;
|
||||||
memory->p->errstr = GBA_CANNOT_MMAP;
|
memory->p->errstr = GBA_CANNOT_MMAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory->d.activeRegion = 0;
|
||||||
|
memory->d.activeMask = 0;
|
||||||
|
memory->d.setActiveRegion = GBASetActiveRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAMemoryDeinit(struct GBAMemory* memory) {
|
void GBAMemoryDeinit(struct GBAMemory* memory) {
|
||||||
@ -71,6 +77,38 @@ void GBALoadROM(struct GBA* gba, int fd) {
|
|||||||
// TODO: error check
|
// TODO: error check
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) {
|
||||||
|
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||||
|
|
||||||
|
switch (address & ~OFFSET_MASK) {
|
||||||
|
case BASE_BIOS:
|
||||||
|
memory->activeRegion = gbaMemory->bios;
|
||||||
|
memory->activeMask = 0;
|
||||||
|
break;
|
||||||
|
case BASE_WORKING_RAM:
|
||||||
|
memory->activeRegion = gbaMemory->wram;
|
||||||
|
memory->activeMask = SIZE_WORKING_RAM - 1;
|
||||||
|
break;
|
||||||
|
case BASE_WORKING_IRAM:
|
||||||
|
memory->activeRegion = gbaMemory->iwram;
|
||||||
|
memory->activeMask = SIZE_WORKING_IRAM - 1;
|
||||||
|
break;
|
||||||
|
case BASE_CART0:
|
||||||
|
case BASE_CART0_EX:
|
||||||
|
case BASE_CART1:
|
||||||
|
case BASE_CART1_EX:
|
||||||
|
case BASE_CART2:
|
||||||
|
case BASE_CART2_EX:
|
||||||
|
memory->activeRegion = gbaMemory->rom;
|
||||||
|
memory->activeMask = SIZE_CART0 - 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memory->activeRegion = 0;
|
||||||
|
memory->activeMask = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address) {
|
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address) {
|
||||||
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||||||
static const ARMInstruction _armTable[0x1000];
|
static const ARMInstruction _armTable[0x1000];
|
||||||
|
|
||||||
static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory* memory, uint32_t address, uint32_t* opcodeOut) {
|
static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory* memory, uint32_t address, uint32_t* opcodeOut) {
|
||||||
uint32_t opcode = memory->load32(memory, address);
|
uint32_t opcode = memory->activeRegion[(address & memory->activeMask) >> 2];
|
||||||
*opcodeOut = opcode;
|
*opcodeOut = opcode;
|
||||||
return _armTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
|
return _armTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
|
||||||
}
|
}
|
||||||
@ -127,7 +127,8 @@ void ARMStep(struct ARMCore* cpu) {
|
|||||||
// Beware pre-processor antics
|
// Beware pre-processor antics
|
||||||
|
|
||||||
#define ARM_WRITE_PC \
|
#define ARM_WRITE_PC \
|
||||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM
|
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \
|
||||||
|
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]);
|
||||||
|
|
||||||
#define ARM_ADDITION_S(M, N, D) \
|
#define ARM_ADDITION_S(M, N, D) \
|
||||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||||
|
11
src/main.c
11
src/main.c
@ -2,8 +2,9 @@
|
|||||||
#include "gba.h"
|
#include "gba.h"
|
||||||
#include "isa-arm.h"
|
#include "isa-arm.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
struct GBA gba;
|
struct GBA gba;
|
||||||
@ -11,9 +12,13 @@ int main(int argc, char** argv) {
|
|||||||
int fd = open("test.rom", O_RDONLY);
|
int fd = open("test.rom", O_RDONLY);
|
||||||
GBALoadROM(&gba, fd);
|
GBALoadROM(&gba, fd);
|
||||||
gba.cpu.gprs[ARM_PC] = 0x08000004;
|
gba.cpu.gprs[ARM_PC] = 0x08000004;
|
||||||
ARMStep(&gba.cpu);
|
gba.memory.d.setActiveRegion(&gba.memory.d, gba.cpu.gprs[ARM_PC]);
|
||||||
ARMStep(&gba.cpu);
|
int i;
|
||||||
|
for (i = 0; i < 1024 * 1024 * 16; ++i) {
|
||||||
|
ARMStep(&gba.cpu);
|
||||||
|
}
|
||||||
GBADeinit(&gba);
|
GBADeinit(&gba);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user