From 4fbc43b4ee193d88efa03e6cb9b1d77b44051365 Mon Sep 17 00:00:00 2001 From: clobber Date: Tue, 7 Apr 2020 15:13:15 -0600 Subject: [PATCH] Update to mGBA 0.8.1 --- Info.plist | 2 +- src/core/core.c | 2 +- src/gb/audio.c | 8 ++++-- src/gb/debugger/cli.c | 6 ++++ src/gba/audio.c | 4 +-- src/gba/core.c | 2 +- src/gba/debugger/cli.c | 6 ++++ src/gba/gba.c | 2 +- src/gba/hle-bios.c | 7 +++-- src/gba/hle-bios.s | 5 ++++ src/gba/io.c | 9 +++--- src/gba/memory.c | 20 +++++++------ src/gba/renderers/gl.c | 7 +++-- src/gba/renderers/video-software.c | 2 +- src/util/elf-read.c | 3 ++ src/util/vfs/vfs-fd.c | 46 +++++++++++++++++++++++++----- 16 files changed, 96 insertions(+), 35 deletions(-) diff --git a/Info.plist b/Info.plist index 4c0b80f..3ae5a7b 100644 --- a/Info.plist +++ b/Info.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 0.8.0 + 0.8.1 NSPrincipalClass OEGameCoreController OEGameCoreClass diff --git a/src/core/core.c b/src/core/core.c index 0a79eab..79723c4 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -370,7 +370,7 @@ bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { Elf32_Phdr* phdr = ELFProgramHeadersGetPointer(&ph, i); void* block = mCoreGetMemoryBlock(core, phdr->p_paddr, &bsize); char* bytes = ELFBytes(elf, &esize); - if (block && bsize >= phdr->p_filesz && esize >= phdr->p_filesz + phdr->p_offset) { + if (block && bsize >= phdr->p_filesz && bsize > phdr->p_offset && esize >= phdr->p_filesz + phdr->p_offset) { memcpy(block, &bytes[phdr->p_offset], phdr->p_filesz); } else { return false; diff --git a/src/gb/audio.c b/src/gb/audio.c index 63af6bc..4bc5fa3 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -1078,9 +1078,13 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt LOAD_32LE(audio->ch4.lastEvent, 0, &state->ch4.lastEvent); LOAD_32LE(when, 0, &state->ch4.nextEvent); if (audio->ch4.envelope.dead < 2 && audio->playingCh4) { - if (when - audio->ch4.lastEvent > (uint32_t) audio->sampleInterval) { + if (!audio->ch4.lastEvent) { // Back-compat: fake this value - audio->ch4.lastEvent = when - audio->sampleInterval; + uint32_t currentTime = mTimingCurrentTime(audio->timing); + int32_t cycles = audio->ch4.ratio ? 2 * audio->ch4.ratio : 1; + cycles <<= audio->ch4.frequency; + cycles *= 8 * audio->timingFactor; + audio->ch4.lastEvent = currentTime + (when & (cycles - 1)) - cycles; } mTimingSchedule(audio->timing, &audio->ch4Event, when); } diff --git a/src/gb/debugger/cli.c b/src/gb/debugger/cli.c index 9ad6cdd..cba9f4a 100644 --- a/src/gb/debugger/cli.c +++ b/src/gb/debugger/cli.c @@ -16,13 +16,17 @@ static void _GBCLIDebuggerInit(struct CLIDebuggerSystem*); static bool _GBCLIDebuggerCustom(struct CLIDebuggerSystem*); static void _frame(struct CLIDebugger*, struct CLIDebugVector*); +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); +#endif struct CLIDebuggerCommandSummary _GBCLIDebuggerCommands[] = { { "frame", _frame, "", "Frame advance" }, +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 { "load", _load, "*", "Load a savestate" }, { "save", _save, "*", "Save a savestate" }, +#endif { 0, 0, 0, 0 } }; @@ -73,6 +77,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { gbDebugger->inVblank = GBRegisterSTATGetMode(((struct GB*) gbDebugger->core->board)->memory.io[REG_STAT]) == 1; } +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { @@ -106,3 +111,4 @@ static void _save(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { mCoreSaveState(gbDebugger->core, dv->intValue, SAVESTATE_SCREENSHOT | SAVESTATE_RTC | SAVESTATE_METADATA); } +#endif diff --git a/src/gba/audio.c b/src/gba/audio.c index d2650d6..72f49b7 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -104,6 +104,8 @@ void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) { } void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) { + info->reg = GBADMARegisterSetDestControl(info->reg, GBA_DMA_FIXED); + info->reg = GBADMARegisterSetWidth(info->reg, 1); switch (info->dest) { case BASE_IO | REG_FIFO_A_LO: audio->chA.dmaSource = number; @@ -129,8 +131,6 @@ void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* audio->externalMixing = false; } } - info->reg = GBADMARegisterSetDestControl(info->reg, GBA_DMA_FIXED); - info->reg = GBADMARegisterSetWidth(info->reg, 1); } void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) { diff --git a/src/gba/core.c b/src/gba/core.c index 3c1ba6d..5d027c0 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -608,7 +608,7 @@ static void _GBACoreReset(struct mCore* core) { #endif ARMReset(core->cpu); - if (core->opts.skipBios && (gba->romVf || gba->memory.rom)) { + if ((core->opts.skipBios && (gba->romVf || gba->memory.rom)) || (gba->romVf && GBAIsMB(gba->romVf))) { GBASkipBIOS(core->board); } } diff --git a/src/gba/debugger/cli.c b/src/gba/debugger/cli.c index 643a12b..5349911 100644 --- a/src/gba/debugger/cli.c +++ b/src/gba/debugger/cli.c @@ -16,13 +16,17 @@ static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*); static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem*); static void _frame(struct CLIDebugger*, struct CLIDebugVector*); +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); +#endif struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = { { "frame", _frame, "", "Frame advance" }, +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 { "load", _load, "*", "Load a savestate" }, { "save", _save, "*", "Save a savestate" }, +#endif { 0, 0, 0, 0 } }; @@ -72,6 +76,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1]); } +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { @@ -107,3 +112,4 @@ static void _save(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { mCoreSaveState(gbaDebugger->core, dv->intValue, SAVESTATE_SCREENSHOT | SAVESTATE_RTC | SAVESTATE_METADATA); } +#endif diff --git a/src/gba/gba.c b/src/gba/gba.c index 7c00151..769e85b 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -257,7 +257,7 @@ void GBASkipBIOS(struct GBA* gba) { if (gba->memory.rom) { cpu->gprs[ARM_PC] = BASE_CART0; } else { - cpu->gprs[ARM_PC] = BASE_WORKING_RAM; + cpu->gprs[ARM_PC] = BASE_WORKING_RAM + 0xC0; } gba->video.vcount = 0x7D; gba->memory.io[REG_VCOUNT >> 1] = 0x7D; diff --git a/src/gba/hle-bios.c b/src/gba/hle-bios.c index 776c3d5..8903ca0 100644 --- a/src/gba/hle-bios.c +++ b/src/gba/hle-bios.c @@ -3,10 +3,10 @@ #include const uint8_t hleBios[SIZE_BIOS] = { - 0x06, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x0b, 0x00, 0x00, 0xea, + 0x06, 0x00, 0x00, 0xea, 0x88, 0x00, 0x00, 0xea, 0x0b, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe1, 0x2c, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x03, 0xa0, 0xe3, - 0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0xf8, 0x01, 0x9f, 0x15, + 0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0x04, 0x02, 0x9f, 0x15, 0x10, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x29, 0xe1, 0x00, 0x00, 0x5d, 0xe3, 0x01, 0xd3, 0xa0, 0x03, 0x20, 0xd0, 0x4d, 0x02, 0x00, 0x58, 0x2d, 0xe9, 0x02, 0xb0, 0x5e, 0xe5, 0x9c, 0xc0, 0xa0, 0xe3, @@ -49,5 +49,6 @@ const uint8_t hleBios[SIZE_BIOS] = { 0x03, 0xa0, 0xa0, 0xe1, 0x02, 0x00, 0x51, 0xe1, 0xf8, 0x07, 0xa1, 0xb8, 0xfc, 0xff, 0xff, 0xba, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x51, 0xe1, 0xf8, 0x07, 0xb0, 0xb8, 0xf8, 0x07, 0xa1, 0xb8, 0xfb, 0xff, 0xff, 0xba, - 0xf0, 0x87, 0xbd, 0xe8, 0xc0, 0x00, 0x00, 0x02 + 0xf0, 0x87, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xe0, 0xa0, 0x03, 0xc0, 0x00, 0x00, 0x02 }; diff --git a/src/gba/hle-bios.s b/src/gba/hle-bios.s index 96de3ad..bb7eb0c 100644 --- a/src/gba/hle-bios.s +++ b/src/gba/hle-bios.s @@ -187,4 +187,9 @@ blt 0b 2: ldmfd sp!, {r4-r10, pc} +undefBase: +subs pc, lr, #4 +.word 0 +.word 0x03A0E004 + .ltorg diff --git a/src/gba/io.c b/src/gba/io.c index 2b74dd9..65cf1e6 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -950,7 +950,7 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) { STORE_32(gba->memory.dma[i].when, 0, &state->dma[i].when); } - state->dmaTransferRegister = gba->memory.dmaTransferRegister; + STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister); GBAHardwareSerialize(&gba->memory.hw, state); } @@ -988,12 +988,11 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) { LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest); LOAD_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount); LOAD_32(gba->memory.dma[i].when, 0, &state->dma[i].when); - if (GBADMARegisterGetTiming(gba->memory.dma[i].reg) != GBA_DMA_TIMING_NOW) { - GBADMASchedule(gba, i, &gba->memory.dma[i]); - } } GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]); - gba->memory.dmaTransferRegister = state->dmaTransferRegister; + + LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister); + GBADMAUpdate(gba); GBAHardwareDeserialize(&gba->memory.hw, state); } diff --git a/src/gba/memory.c b/src/gba/memory.c index 091bfa1..d2ba5a4 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -772,12 +772,12 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { #define STORE_SRAM \ if (address & 0x3) { \ mLOG(GBA_MEM, GAME_ERROR, "Unaligned SRAM Store32: 0x%08X", address); \ - value = 0; \ - } \ - GBAStore8(cpu, address & ~0x3, value, cycleCounter); \ - GBAStore8(cpu, (address & ~0x3) | 1, value, cycleCounter); \ - GBAStore8(cpu, (address & ~0x3) | 2, value, cycleCounter); \ - GBAStore8(cpu, (address & ~0x3) | 3, value, cycleCounter); + } else { \ + GBAStore8(cpu, address, value, cycleCounter); \ + GBAStore8(cpu, address | 1, value, cycleCounter); \ + GBAStore8(cpu, address | 2, value, cycleCounter); \ + GBAStore8(cpu, address | 3, value, cycleCounter); \ + } #define STORE_BAD \ mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store32: 0x%08X", address); @@ -923,8 +923,12 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle break; case REGION_CART_SRAM: case REGION_CART_SRAM_MIRROR: - GBAStore8(cpu, (address & ~0x1), value, cycleCounter); - GBAStore8(cpu, (address & ~0x1) | 1, value, cycleCounter); + if (address & 1) { + mLOG(GBA_MEM, GAME_ERROR, "Unaligned SRAM Store16: 0x%08X", address); + break; + } + GBAStore8(cpu, address, value, cycleCounter); + GBAStore8(cpu, address | 1, value, cycleCounter); break; default: mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store16: 0x%08X", address); diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 3c433e8..7f55333 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -931,6 +931,7 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glRenderer->oamDirty = true; glRenderer->paletteDirty = true; glRenderer->vramDirty = 0xFFFFFF; glRenderer->firstAffine = -1; @@ -1727,13 +1728,13 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glStencilFunc(GL_EQUAL, 1, 1); glUseProgram(shader->program); glDrawBuffers(2, (GLenum[]) { GL_NONE, GL_COLOR_ATTACHMENT1 }); - glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); glBindVertexArray(shader->vao); glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], totalWidth, totalHeight); - glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c), 0, 0, 0); + glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c), + (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (renderer->blendEffect * 4), + renderer->blda, GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 666baa5..00a76cf 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -623,7 +623,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render _drawScanline(softwareRenderer, y); - if (softwareRenderer->forceTarget1 && softwareRenderer->target2Bd) { + if ((softwareRenderer->forceTarget1 || softwareRenderer->bg[0].target1 || softwareRenderer->bg[1].target1 || softwareRenderer->bg[2].target1 || softwareRenderer->bg[3].target1) && softwareRenderer->target2Bd) { x = 0; for (w = 0; w < softwareRenderer->nWindows; ++w) { uint32_t backdrop = 0; diff --git a/src/util/elf-read.c b/src/util/elf-read.c index 8ac3877..520c01c 100644 --- a/src/util/elf-read.c +++ b/src/util/elf-read.c @@ -84,6 +84,9 @@ void ELFGetProgramHeaders(struct ELF* elf, struct ELFProgramHeaders* ph) { ELFProgramHeadersClear(ph); Elf32_Ehdr* hdr = elf32_getehdr(elf->e); Elf32_Phdr* phdr = elf32_getphdr(elf->e); + if (!hdr || !phdr) { + return; + } ELFProgramHeadersResize(ph, hdr->e_phnum); memcpy(ELFProgramHeadersGetPointer(ph, 0), phdr, sizeof(*phdr) * hdr->e_phnum); } diff --git a/src/util/vfs/vfs-fd.c b/src/util/vfs/vfs-fd.c index ed22225..dde2397 100644 --- a/src/util/vfs/vfs-fd.c +++ b/src/util/vfs/vfs-fd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2020 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -14,11 +14,23 @@ #include #endif +#include + +#ifdef _WIN32 +struct HandleMappingTuple { + HANDLE handle; + void* mapping; +}; + +DECLARE_VECTOR(HandleMappingList, struct HandleMappingTuple); +DEFINE_VECTOR(HandleMappingList, struct HandleMappingTuple); +#endif + struct VFileFD { struct VFile d; int fd; #ifdef _WIN32 - HANDLE hMap; + struct HandleMappingList handles; #endif }; @@ -74,12 +86,23 @@ struct VFile* VFileFromFD(int fd) { vfd->d.truncate = _vfdTruncate; vfd->d.size = _vfdSize; vfd->d.sync = _vfdSync; +#ifdef _WIN32 + HandleMappingListInit(&vfd->handles, 4); +#endif return &vfd->d; } bool _vfdClose(struct VFile* vf) { struct VFileFD* vfd = (struct VFileFD*) vf; +#ifdef _WIN32 + size_t i; + for (i = 0; i < HandleMappingListSize(&vfd->handles); ++i) { + UnmapViewOfFile(HandleMappingListGetPointer(&vfd->handles, i)->mapping); + CloseHandle(HandleMappingListGetPointer(&vfd->handles, i)->handle); + } + HandleMappingListDeinit(&vfd->handles); +#endif if (close(vfd->fd) < 0) { return false; } @@ -134,16 +157,25 @@ static void* _vfdMap(struct VFile* vf, size_t size, int flags) { if (size > fileSize) { size = fileSize; } - vfd->hMap = CreateFileMapping((HANDLE) _get_osfhandle(vfd->fd), 0, createFlags, 0, size & 0xFFFFFFFF, 0); - return MapViewOfFile(vfd->hMap, mapFiles, 0, 0, size); + struct HandleMappingTuple tuple = {0}; + tuple.handle = CreateFileMapping((HANDLE) _get_osfhandle(vfd->fd), 0, createFlags, 0, size & 0xFFFFFFFF, 0); + tuple.mapping = MapViewOfFile(tuple.handle, mapFiles, 0, 0, size); + *HandleMappingListAppend(&vfd->handles) = tuple; + return tuple.mapping; } static void _vfdUnmap(struct VFile* vf, void* memory, size_t size) { UNUSED(size); struct VFileFD* vfd = (struct VFileFD*) vf; - UnmapViewOfFile(memory); - CloseHandle(vfd->hMap); - vfd->hMap = 0; + size_t i; + for (i = 0; i < HandleMappingListSize(&vfd->handles); ++i) { + if (HandleMappingListGetPointer(&vfd->handles, i)->mapping == memory) { + UnmapViewOfFile(memory); + CloseHandle(HandleMappingListGetPointer(&vfd->handles, i)->handle); + HandleMappingListShift(&vfd->handles, i, 1); + break; + } + } } #endif