all repos — mgba @ 84ad94b85e5c6fc8a0c1cd5c0dfca9809d2aeca7

mGBA Game Boy Advance Emulator

Support loading BIOS
Jeffrey Pfau jeffrey@endrift.com
Tue, 08 Oct 2013 22:36:19 -0700
commit

84ad94b85e5c6fc8a0c1cd5c0dfca9809d2aeca7

parent

68d85ab9b7f460dbc06fbd209770ef029169cce7

5 files changed, 35 insertions(+), 3 deletions(-)

jump to
M src/gba/gba-bios.csrc/gba/gba-bios.c

@@ -162,6 +162,10 @@ }

void GBASwi16(struct ARMBoard* board, int immediate) { struct GBA* gba = ((struct GBABoard*) board)->p; + if (gba->memory.fullBios) { + ARMRaiseSWI(&gba->cpu); + return; + } switch (immediate) { case 0x1: _RegisterRamReset(gba);
M src/gba/gba-memory.csrc/gba/gba-memory.c

@@ -31,6 +31,7 @@ memory->d.store16 = GBAStore16;

memory->d.store8 = GBAStore8; memory->bios = (uint32_t*) hleBios; + memory->fullBios = 0; memory->wram = mmap(0, SIZE_WORKING_RAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); memory->iwram = mmap(0, SIZE_WORKING_IRAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); memory->rom = 0;

@@ -125,7 +126,7 @@

switch (address & ~OFFSET_MASK) { case BASE_BIOS: if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) { - if (address < hleBiosLength) { + if (address < SIZE_BIOS) { value = gbaMemory->bios[address >> 2]; } else { value = 0;

@@ -198,7 +199,15 @@ int wait = 0;

switch (address & ~OFFSET_MASK) { case BASE_BIOS: - GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load16: 0x%08X", address); + if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) { + if (address < SIZE_BIOS) { + value = ((int16_t*) gbaMemory->bios)[address >> 1]; + } else { + value = 0; + } + } else { + value = gbaMemory->biosPrefetch; + } break; case BASE_WORKING_RAM: value = ((int16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1];

@@ -265,7 +274,15 @@ int wait = 0;

switch (address & ~OFFSET_MASK) { case BASE_BIOS: - GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address); + if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) { + if (address < SIZE_BIOS) { + value = ((int8_t*) gbaMemory->bios)[address]; + } else { + value = 0; + } + } else { + value = gbaMemory->biosPrefetch; + } break; case BASE_WORKING_RAM: value = ((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)];
M src/gba/gba-memory.hsrc/gba/gba-memory.h

@@ -114,6 +114,7 @@ uint16_t io[SIZE_IO >> 1];

struct GBASavedata savedata; size_t romSize; + int fullBios; char waitstates32[256]; char waitstates16[256];
M src/gba/gba.csrc/gba/gba.c

@@ -271,6 +271,15 @@ gba->memory.romSize = info.st_size;

// TODO: error check } +void GBALoadBIOS(struct GBA* gba, int fd) { + gba->memory.bios = mmap(0, SIZE_BIOS, PROT_READ, MAP_SHARED, fd, 0); + gba->memory.fullBios = 1; + if ((gba->cpu.gprs[ARM_PC] >> BASE_OFFSET) == BASE_BIOS) { + gba->memory.d.setActiveRegion(&gba->memory.d, gba->cpu.gprs[ARM_PC]); + } + // TODO: error check +} + void GBATimerUpdateRegister(struct GBA* gba, int timer) { struct GBATimer* currentTimer = &gba->timers[timer]; if (currentTimer->enable && !currentTimer->countUp) {
M src/gba/gba.hsrc/gba/gba.h

@@ -116,6 +116,7 @@

void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger); void GBALoadROM(struct GBA* gba, int fd, const char* fname); +void GBALoadBIOS(struct GBA* gba, int fd); __attribute__((format (printf, 3, 4))) void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...);