mirror of https://github.com/mgba-emu/mgba.git
GBA Memory: Use a dynamically sized mask for ROM memory
This commit is contained in:
parent
76663c41cd
commit
003a21b13d
1
CHANGES
1
CHANGES
|
@ -5,6 +5,7 @@ Bugfixes:
|
|||
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:
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "util/crc32.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/math.h"
|
||||
#include "util/patch.h"
|
||||
#include "util/vfs.h"
|
||||
|
||||
|
@ -156,6 +157,7 @@ void GBAReset(struct ARMCore* cpu) {
|
|||
|
||||
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 @@ void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char
|
|||
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 GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char
|
|||
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 @@ void GBAApplyPatch(struct GBA* gba, struct Patch* patch) {
|
|||
return;
|
||||
}
|
||||
gba->memory.romSize = patchedSize;
|
||||
gba->memory.romMask = SIZE_CART0 - 1;
|
||||
gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ void GBAMemoryInit(struct GBA* gba) {
|
|||
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 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||
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 @@ void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* o
|
|||
_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 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o
|
|||
_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 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old)
|
|||
_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;
|
||||
|
|
|
@ -118,6 +118,7 @@ struct GBAMemory {
|
|||
struct GBACartridgeHardware hw;
|
||||
struct GBASavedata savedata;
|
||||
size_t romSize;
|
||||
uint32_t romMask;
|
||||
uint16_t romID;
|
||||
int fullBios;
|
||||
|
||||
|
|
|
@ -14,4 +14,46 @@ static inline uint32_t popcount32(unsigned bits) {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue