From 84ad94b85e5c6fc8a0c1cd5c0dfca9809d2aeca7 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 8 Oct 2013 22:36:19 -0700 Subject: [PATCH] Support loading BIOS --- src/gba/gba-bios.c | 4 ++++ src/gba/gba-memory.c | 23 ++++++++++++++++++++--- src/gba/gba-memory.h | 1 + src/gba/gba.c | 9 +++++++++ src/gba/gba.h | 1 + 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/gba/gba-bios.c b/src/gba/gba-bios.c index 10210f62d..5a02d3a9b 100644 --- a/src/gba/gba-bios.c +++ b/src/gba/gba-bios.c @@ -162,6 +162,10 @@ static void _MidiKey2Freq(struct GBA* gba) { 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); diff --git a/src/gba/gba-memory.c b/src/gba/gba-memory.c index a935ec0cf..94589cc91 100644 --- a/src/gba/gba-memory.c +++ b/src/gba/gba-memory.c @@ -31,6 +31,7 @@ void GBAMemoryInit(struct GBAMemory* memory) { 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 @@ int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter) 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 @@ int16_t GBALoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) 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 @@ int8_t GBALoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) { 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)]; diff --git a/src/gba/gba-memory.h b/src/gba/gba-memory.h index eb3aee072..b28973134 100644 --- a/src/gba/gba-memory.h +++ b/src/gba/gba-memory.h @@ -114,6 +114,7 @@ struct GBAMemory { struct GBASavedata savedata; size_t romSize; + int fullBios; char waitstates32[256]; char waitstates16[256]; diff --git a/src/gba/gba.c b/src/gba/gba.c index 88e8159b8..996de0327 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -271,6 +271,15 @@ void GBALoadROM(struct GBA* gba, int fd, const char* fname) { // 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) { diff --git a/src/gba/gba.h b/src/gba/gba.h index 075273f2f..88bc35b41 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -116,6 +116,7 @@ int GBAHalt(struct GBA* gba); 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, ...);