From 2969a8bf7a25e00616436b43c7a5e11255f20070 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 Jun 2022 21:10:16 -0700 Subject: [PATCH] Core: Fix cache writes that span multiple tiles --- include/mgba/core/map-cache.h | 1 + src/core/map-cache.c | 17 +++++++++++++---- src/gb/renderers/cache-set.c | 1 + src/gba/renderers/cache-set.c | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/mgba/core/map-cache.h b/include/mgba/core/map-cache.h index 2bd5934e8..349fc1663 100644 --- a/include/mgba/core/map-cache.h +++ b/include/mgba/core/map-cache.h @@ -23,6 +23,7 @@ DECL_BITS(mMapCacheSystemInfo, TilesWide, 8, 4); DECL_BITS(mMapCacheSystemInfo, TilesHigh, 12, 4); DECL_BITS(mMapCacheSystemInfo, MacroTileSize, 16, 7); DECL_BITS(mMapCacheSystemInfo, MapAlign, 23, 2); +DECL_BITS(mMapCacheSystemInfo, WriteAlign, 25, 2); DECL_BITFIELD(mMapCacheEntryFlags, uint16_t); DECL_BITS(mMapCacheEntryFlags, PaletteId, 0, 4); diff --git a/src/core/map-cache.c b/src/core/map-cache.c index 17df206dd..d51800780 100644 --- a/src/core/map-cache.c +++ b/src/core/map-cache.c @@ -70,11 +70,20 @@ void mMapCacheDeinit(struct mMapCache* cache) { void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address) { if (address >= cache->mapStart && address < cache->mapStart + cache->mapSize) { + uint32_t align = 1 << (mMapCacheSystemInfoGetWriteAlign(cache->sysConfig) - mMapCacheSystemInfoGetMapAlign(cache->sysConfig)); address -= cache->mapStart; - struct mMapCacheEntry* status = &cache->status[address >> mMapCacheSystemInfoGetMapAlign(cache->sysConfig)]; - ++status->vramVersion; - status->flags = mMapCacheEntryFlagsClearVramClean(status->flags); - status->tileStatus[mMapCacheEntryFlagsGetPaletteId(status->flags)].vramClean = 0; + address >>= mMapCacheSystemInfoGetMapAlign(cache->sysConfig); + + uint32_t i; + for (i = 0; i < align; ++i) { + if (address + i >= (cache->mapSize >> mMapCacheSystemInfoGetMapAlign(cache->sysConfig))) { + break; + } + struct mMapCacheEntry* status = &cache->status[address + i]; + ++status->vramVersion; + status->flags = mMapCacheEntryFlagsClearVramClean(status->flags); + status->tileStatus[mMapCacheEntryFlagsGetPaletteId(status->flags)].vramClean = 0; + } } } diff --git a/src/gb/renderers/cache-set.c b/src/gb/renderers/cache-set.c index ebd0d0899..bfc56c2a3 100644 --- a/src/gb/renderers/cache-set.c +++ b/src/gb/renderers/cache-set.c @@ -119,6 +119,7 @@ void GBVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint16_t address, u sysconfig = mMapCacheSystemInfoSetMacroTileSize(sysconfig, 5); sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 1); sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 0); + sysconfig = mMapCacheSystemInfoSetWriteAlign(sysconfig, 0); sysconfig = mMapCacheSystemInfoSetTilesHigh(sysconfig, 5); sysconfig = mMapCacheSystemInfoSetTilesWide(sysconfig, 5); mMapCacheConfigureSystem(map, sysconfig); diff --git a/src/gba/renderers/cache-set.c b/src/gba/renderers/cache-set.c index 95093ae9a..51512721d 100644 --- a/src/gba/renderers/cache-set.c +++ b/src/gba/renderers/cache-set.c @@ -160,7 +160,7 @@ static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t int size = GBARegisterBGCNTGetSize(value); int tilesWide = 0; int tilesHigh = 0; - mMapCacheSystemInfo sysconfig = 0; + mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoSetWriteAlign(0, 1); if (map->mapParser == mapParser0) { map->tileCache = mTileCacheSetGetPointer(&cache->tiles, p); sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 2 + p);