GBA: Fix calls to endian-independent loadstores

This commit is contained in:
Jeffrey Pfau 2015-06-16 05:15:17 -07:00
parent dc33a4f173
commit 3cddb33288
3 changed files with 79 additions and 78 deletions

View File

@ -43,6 +43,7 @@ Bugfixes:
- GBA Audio: Fix audio pitch changing when adjusting buffer size
- SDL: Fix SDL build when OpenGL is missing
- ARM7: Fix timing of multiplies to use N cycles
- GBA: Fix calls to endian-independent loadstores
Misc:
- Qt: Handle saving input settings better
- Debugger: Free watchpoints in addition to breakpoints

View File

@ -326,30 +326,30 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
}
#define LOAD_WORKING_RAM \
LOAD_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); \
LOAD_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram); \
wait += waitstatesRegion[REGION_WORKING_RAM];
#define LOAD_WORKING_IRAM LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
#define LOAD_WORKING_IRAM LOAD_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
#define LOAD_IO value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
#define LOAD_PALETTE_RAM \
LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \
LOAD_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
++wait;
#define LOAD_VRAM \
if ((address & 0x0001FFFF) < SIZE_VRAM) { \
LOAD_32(value, address & 0x0001FFFF, gba->video.renderer->vram); \
LOAD_32(value, address & 0x0001FFFC, gba->video.renderer->vram); \
} else { \
LOAD_32(value, address & 0x00017FFF, gba->video.renderer->vram); \
LOAD_32(value, address & 0x00017FFC, gba->video.renderer->vram); \
} \
++wait;
#define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
#define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw);
#define LOAD_CART \
wait += waitstatesRegion[address >> BASE_OFFSET]; \
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
LOAD_32(value, address & (SIZE_CART0 - 1), memory->rom); \
LOAD_32(value, address & (SIZE_CART0 - 4), memory->rom); \
} else { \
GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
value = (address >> 1) & 0xFFFF; \
@ -440,27 +440,27 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
}
break;
case REGION_WORKING_RAM:
LOAD_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
LOAD_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
break;
case REGION_WORKING_IRAM:
LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
LOAD_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
break;
case REGION_IO:
value = GBAIORead(gba, address & (SIZE_IO - 1));
value = GBAIORead(gba, address & (SIZE_IO - 2));
break;
case REGION_PALETTE_RAM:
LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
LOAD_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
break;
case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_VRAM) {
LOAD_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
LOAD_16(value, address & 0x0001FFFE, gba->video.renderer->vram);
} else {
LOAD_16(value, address & 0x00017FFF, gba->video.renderer->vram);
LOAD_16(value, address & 0x00017FFE, gba->video.renderer->vram);
}
break;
case REGION_OAM:
LOAD_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
LOAD_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
break;
case REGION_CART0:
case REGION_CART0_EX:
@ -469,7 +469,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
case REGION_CART2:
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
} else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
value = (address >> 1) & 0xFFFF; \
@ -480,7 +480,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
if (memory->savedata.type == SAVEDATA_EEPROM) {
value = GBASavedataReadEEPROM(&memory->savedata);
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
} else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
value = (address >> 1) & 0xFFFF; \
@ -599,31 +599,31 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
}
#define STORE_WORKING_RAM \
STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); \
STORE_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram); \
wait += waitstatesRegion[REGION_WORKING_RAM];
#define STORE_WORKING_IRAM \
STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
STORE_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
#define STORE_IO \
GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
GBAIOWrite32(gba, address & (SIZE_IO - 4), value);
#define STORE_PALETTE_RAM \
STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16); \
STORE_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16); \
++wait; \
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 4), value);
#define STORE_VRAM \
if ((address & 0x0001FFFF) < SIZE_VRAM) { \
STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram); \
STORE_32(value, address & 0x0001FFFC, gba->video.renderer->vram); \
} else { \
STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram); \
STORE_32(value, address & 0x00017FFC, gba->video.renderer->vram); \
} \
++wait;
#define STORE_OAM \
STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw); \
STORE_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw); \
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1); \
gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
@ -691,33 +691,33 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
switch (address >> BASE_OFFSET) {
case REGION_WORKING_RAM:
STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
STORE_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
break;
case REGION_WORKING_IRAM:
STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
STORE_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
break;
case REGION_IO:
GBAIOWrite(gba, address & (SIZE_IO - 1), value);
GBAIOWrite(gba, address & (SIZE_IO - 2), value);
break;
case REGION_PALETTE_RAM:
STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
STORE_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
break;
case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_VRAM) {
STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
STORE_16(value, address & 0x0001FFFE, gba->video.renderer->vram);
} else {
STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
STORE_16(value, address & 0x00017FFE, gba->video.renderer->vram);
}
break;
case REGION_OAM:
STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
STORE_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
break;
case REGION_CART0:
if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFF)) {
uint32_t reg = address & 0xFFFFFF;
if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFE)) {
uint32_t reg = address & 0xFFFFFE;
GBAHardwareGPIOWrite(&memory->hw, reg, value);
} else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
@ -817,36 +817,36 @@ void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* o
switch (address >> BASE_OFFSET) {
case REGION_WORKING_RAM:
LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 1), memory->wram);
STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 4), memory->wram);
STORE_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram);
break;
case REGION_WORKING_IRAM:
LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
STORE_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
break;
case REGION_IO:
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch32: 0x%08X", address);
break;
case REGION_PALETTE_RAM:
LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
STORE_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 4), value);
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16);
break;
case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_VRAM) {
LOAD_32(oldValue, address & 0x0001FFFF, gba->video.renderer->vram);
STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
LOAD_32(oldValue, address & 0x0001FFFC, gba->video.renderer->vram);
STORE_32(value, address & 0x0001FFFC, gba->video.renderer->vram);
} else {
LOAD_32(oldValue, address & 0x00017FFF, gba->video.renderer->vram);
STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram);
LOAD_32(oldValue, address & 0x00017FFC, gba->video.renderer->vram);
STORE_32(value, address & 0x00017FFC, gba->video.renderer->vram);
}
break;
case REGION_OAM:
LOAD_32(oldValue, address & (SIZE_OAM - 1), gba->video.oam.raw);
STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 1)) + 2) >> 1);
LOAD_32(oldValue, address & (SIZE_OAM - 4), gba->video.oam.raw);
STORE_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw);
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) + 2) >> 1);
break;
case REGION_CART0:
case REGION_CART0_EX:
@ -855,17 +855,17 @@ void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* o
case REGION_CART2:
case REGION_CART2_EX:
_pristineCow(gba);
if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
if ((address & (SIZE_CART0 - 4)) >= gba->memory.romSize) {
gba->memory.romSize = (address & (SIZE_CART0 - 4)) + 4;
}
LOAD_32(oldValue, address & (SIZE_CART0 - 1), gba->memory.rom);
STORE_32(value, address & (SIZE_CART0 - 1), gba->memory.rom);
LOAD_32(oldValue, address & (SIZE_CART0 - 4), gba->memory.rom);
STORE_32(value, address & (SIZE_CART0 - 4), gba->memory.rom);
break;
case REGION_CART_SRAM:
case REGION_CART_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) {
LOAD_32(oldValue, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
STORE_32(value, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
LOAD_32(oldValue, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
STORE_32(value, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
} else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
}
@ -886,34 +886,34 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o
switch (address >> BASE_OFFSET) {
case REGION_WORKING_RAM:
LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 1), memory->wram);
STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 2), memory->wram);
STORE_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
break;
case REGION_WORKING_IRAM:
LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
STORE_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
break;
case REGION_IO:
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch16: 0x%08X", address);
break;
case REGION_PALETTE_RAM:
LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
STORE_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
break;
case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_VRAM) {
LOAD_16(oldValue, address & 0x0001FFFF, gba->video.renderer->vram);
STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
LOAD_16(oldValue, address & 0x0001FFFE, gba->video.renderer->vram);
STORE_16(value, address & 0x0001FFFE, gba->video.renderer->vram);
} else {
LOAD_16(oldValue, address & 0x00017FFF, gba->video.renderer->vram);
STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
LOAD_16(oldValue, address & 0x00017FFE, gba->video.renderer->vram);
STORE_16(value, address & 0x00017FFE, gba->video.renderer->vram);
}
break;
case REGION_OAM:
LOAD_16(oldValue, address & (SIZE_OAM - 1), gba->video.oam.raw);
STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
LOAD_16(oldValue, address & (SIZE_OAM - 2), gba->video.oam.raw);
STORE_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
break;
case REGION_CART0:
case REGION_CART0_EX:
@ -925,14 +925,14 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o
if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2;
}
LOAD_16(oldValue, address & (SIZE_CART0 - 1), gba->memory.rom);
STORE_16(value, address & (SIZE_CART0 - 1), gba->memory.rom);
LOAD_16(oldValue, address & (SIZE_CART0 - 2), gba->memory.rom);
STORE_16(value, address & (SIZE_CART0 - 2), gba->memory.rom);
break;
case REGION_CART_SRAM:
case REGION_CART_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) {
LOAD_16(oldValue, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
STORE_16(value, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
LOAD_16(oldValue, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
STORE_16(value, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
} else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
}

View File

@ -1723,7 +1723,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
#define SPRITE_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * (GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? width >> 1 : 0x80) + (localY & 0x7) * 4;
#define SPRITE_DRAW_PIXEL_16_NORMAL(localX) \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFF), vramBase); \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \
tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
current = renderer->spriteLayer[outX]; \
if ((current & FLAG_ORDER_MASK) > flags) { \
@ -1735,7 +1735,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
}
#define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFF), vramBase); \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \
tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
if (tileData) { \
renderer->row[outX] |= FLAG_OBJWIN; \
@ -1745,7 +1745,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
#define SPRITE_YBASE_256(localY) unsigned yBase = (localY & ~0x7) * (GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? width : 0x80) + (localY & 0x7) * 8;
#define SPRITE_DRAW_PIXEL_256_NORMAL(localX) \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFF), vramBase); \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \
tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
current = renderer->spriteLayer[outX]; \
if ((current & FLAG_ORDER_MASK) > flags) { \
@ -1757,7 +1757,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
}
#define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFF), vramBase); \
LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \
tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
if (tileData) { \
renderer->row[outX] |= FLAG_OBJWIN; \