all repos — mgba @ 003a21b13d8d563509de5d20966b7c03b14c626f

mGBA Game Boy Advance Emulator

GBA Memory: Use a dynamically sized mask for ROM memory
Jeffrey Pfau jeffrey@endrift.com
Tue, 18 Aug 2015 23:23:45 -0700
commit

003a21b13d8d563509de5d20966b7c03b14c626f

parent

76663c41cdceab9fd4277c0d0e2a0c462167e3d7

5 files changed, 54 insertions(+), 1 deletions(-)

jump to
M CHANGESCHANGES

@@ -5,6 +5,7 @@ - Qt: Fix install path of XDG desktop file with DESTDIR

Misc: - Qt: Window size command line options are now supported - Qt: Increase usability of key mapper + - GBA Memory: Use a dynamically sized mask for ROM memory 0.3.0: (2015-08-16) Features:
M src/gba/gba.csrc/gba/gba.c

@@ -17,6 +17,7 @@ #include "isa-inlines.h"

#include "util/crc32.h" #include "util/memory.h" +#include "util/math.h" #include "util/patch.h" #include "util/vfs.h"

@@ -156,6 +157,7 @@ }

if (gba->yankedRomSize) { gba->memory.romSize = gba->yankedRomSize; + gba->memory.romMask = toPow2(gba->memory.romSize) - 1; gba->yankedRomSize = 0; } GBAMemoryReset(gba);

@@ -403,6 +405,7 @@ gba->yankedRomSize = 0;

gba->memory.rom = gba->pristineRom; gba->activeFile = fname; gba->memory.romSize = gba->pristineRomSize; + gba->memory.romMask = toPow2(gba->memory.romSize) - 1; gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize); GBASavedataInit(&gba->memory.savedata, sav); GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]);

@@ -412,6 +415,7 @@

void GBAYankROM(struct GBA* gba) { gba->yankedRomSize = gba->memory.romSize; gba->memory.romSize = 0; + gba->memory.romMask = 0; GBARaiseIRQ(gba, IRQ_GAMEPAK); }

@@ -452,6 +456,7 @@ gba->memory.rom = gba->pristineRom;

return; } gba->memory.romSize = patchedSize; + gba->memory.romMask = SIZE_CART0 - 1; gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize); }
M src/gba/memory.csrc/gba/memory.c

@@ -50,6 +50,7 @@ gba->memory.wram = 0;

gba->memory.iwram = 0; gba->memory.rom = 0; gba->memory.romSize = 0; + gba->memory.romMask = 0; gba->memory.hw.p = gba; int i;

@@ -269,7 +270,7 @@ case REGION_CART1_EX:

case REGION_CART2: case REGION_CART2_EX: cpu->memory.activeRegion = memory->rom; - cpu->memory.activeMask = SIZE_CART0 - 1; + cpu->memory.activeMask = memory->romMask; if ((address & (SIZE_CART0 - 1)) < memory->romSize) { break; }

@@ -893,6 +894,7 @@ case REGION_CART2_EX:

_pristineCow(gba); if ((address & (SIZE_CART0 - 4)) >= gba->memory.romSize) { gba->memory.romSize = (address & (SIZE_CART0 - 4)) + 4; + gba->memory.romMask = toPow2(gba->memory.romSize) - 1; } LOAD_32(oldValue, address & (SIZE_CART0 - 4), gba->memory.rom); STORE_32(value, address & (SIZE_CART0 - 4), gba->memory.rom);

@@ -960,6 +962,7 @@ case REGION_CART2_EX:

_pristineCow(gba); if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) { gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2; + gba->memory.romMask = toPow2(gba->memory.romSize) - 1; } LOAD_16(oldValue, address & (SIZE_CART0 - 2), gba->memory.rom); STORE_16(value, address & (SIZE_CART0 - 2), gba->memory.rom);

@@ -1017,6 +1020,7 @@ case REGION_CART2_EX:

_pristineCow(gba); if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) { gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2; + gba->memory.romMask = toPow2(gba->memory.romSize) - 1; } oldValue = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)]; ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)] = value;
M src/gba/memory.hsrc/gba/memory.h

@@ -118,6 +118,7 @@

struct GBACartridgeHardware hw; struct GBASavedata savedata; size_t romSize; + uint32_t romMask; uint16_t romID; int fullBios;
M src/util/math.hsrc/util/math.h

@@ -14,4 +14,46 @@ bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);

return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; } +static inline unsigned clz32(uint32_t bits) { +#if defined(__GNUC__) || __clang__ + return __builtin_clz(bits); +#else + static const int table[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (bits & 0xFF000000) { + return table[bits >> 24]; + } else if (bits & 0x00FF0000) { + return table[bits >> 16] + 8; + } else if (bits & 0x0000FF00) { + return table[bits >> 8] + 16; + } + return table[bits] + 24; +#endif +} + +static inline uint32_t toPow2(uint32_t bits) { + if (!bits) { + return 0; + } + unsigned lz = clz32(bits - 1); + return 1 << (32 - lz); +} + #endif