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 - GBA Audio: Fix audio pitch changing when adjusting buffer size
- SDL: Fix SDL build when OpenGL is missing - SDL: Fix SDL build when OpenGL is missing
- ARM7: Fix timing of multiplies to use N cycles - ARM7: Fix timing of multiplies to use N cycles
- GBA: Fix calls to endian-independent loadstores
Misc: Misc:
- Qt: Handle saving input settings better - Qt: Handle saving input settings better
- Debugger: Free watchpoints in addition to breakpoints - 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 \ #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]; 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_IO value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
#define LOAD_PALETTE_RAM \ #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; ++wait;
#define LOAD_VRAM \ #define LOAD_VRAM \
if ((address & 0x0001FFFF) < SIZE_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 { \ } else { \
LOAD_32(value, address & 0x00017FFF, gba->video.renderer->vram); \ LOAD_32(value, address & 0x00017FFC, gba->video.renderer->vram); \
} \ } \
++wait; ++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 \ #define LOAD_CART \
wait += waitstatesRegion[address >> BASE_OFFSET]; \ wait += waitstatesRegion[address >> BASE_OFFSET]; \
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \ 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 { \ } else { \
GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \ GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
value = (address >> 1) & 0xFFFF; \ value = (address >> 1) & 0xFFFF; \
@ -440,27 +440,27 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
} }
break; break;
case REGION_WORKING_RAM: 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]; wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
break; break;
case REGION_WORKING_IRAM: 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; break;
case REGION_IO: case REGION_IO:
value = GBAIORead(gba, address & (SIZE_IO - 1)); value = GBAIORead(gba, address & (SIZE_IO - 2));
break; break;
case REGION_PALETTE_RAM: 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; break;
case REGION_VRAM: case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_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 { } else {
LOAD_16(value, address & 0x00017FFF, gba->video.renderer->vram); LOAD_16(value, address & 0x00017FFE, gba->video.renderer->vram);
} }
break; break;
case REGION_OAM: 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; break;
case REGION_CART0: case REGION_CART0:
case REGION_CART0_EX: case REGION_CART0_EX:
@ -469,7 +469,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
case REGION_CART2: case REGION_CART2:
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { 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 { } else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address); GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
value = (address >> 1) & 0xFFFF; \ 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) { if (memory->savedata.type == SAVEDATA_EEPROM) {
value = GBASavedataReadEEPROM(&memory->savedata); value = GBASavedataReadEEPROM(&memory->savedata);
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) { } 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 { } else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address); GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
value = (address >> 1) & 0xFFFF; \ value = (address >> 1) & 0xFFFF; \
@ -599,31 +599,31 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
} }
#define STORE_WORKING_RAM \ #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]; wait += waitstatesRegion[REGION_WORKING_RAM];
#define STORE_WORKING_IRAM \ #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 \ #define STORE_IO \
GBAIOWrite32(gba, address & (SIZE_IO - 1), value); GBAIOWrite32(gba, address & (SIZE_IO - 4), value);
#define STORE_PALETTE_RAM \ #define STORE_PALETTE_RAM \
STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \ STORE_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16); \ gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16); \
++wait; \ ++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 \ #define STORE_VRAM \
if ((address & 0x0001FFFF) < SIZE_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 { \ } else { \
STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram); \ STORE_32(value, address & 0x00017FFC, gba->video.renderer->vram); \
} \ } \
++wait; ++wait;
#define STORE_OAM \ #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); \
gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 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) { switch (address >> BASE_OFFSET) {
case REGION_WORKING_RAM: 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]; wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
break; break;
case REGION_WORKING_IRAM: 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; break;
case REGION_IO: case REGION_IO:
GBAIOWrite(gba, address & (SIZE_IO - 1), value); GBAIOWrite(gba, address & (SIZE_IO - 2), value);
break; break;
case REGION_PALETTE_RAM: case REGION_PALETTE_RAM:
STORE_16(value, address & (SIZE_PALETTE_RAM - 1), 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 - 1), value); gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
break; break;
case REGION_VRAM: case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_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 { } else {
STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram); STORE_16(value, address & 0x00017FFE, gba->video.renderer->vram);
} }
break; break;
case REGION_OAM: case REGION_OAM:
STORE_16(value, address & (SIZE_OAM - 1), 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 - 1)) >> 1); gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
break; break;
case REGION_CART0: case REGION_CART0:
if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFF)) { if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFE)) {
uint32_t reg = address & 0xFFFFFF; uint32_t reg = address & 0xFFFFFE;
GBAHardwareGPIOWrite(&memory->hw, reg, value); GBAHardwareGPIOWrite(&memory->hw, reg, value);
} else { } else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address); 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) { switch (address >> BASE_OFFSET) {
case REGION_WORKING_RAM: case REGION_WORKING_RAM:
LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 1), memory->wram); LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 4), memory->wram);
STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); STORE_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram);
break; break;
case REGION_WORKING_IRAM: case REGION_WORKING_IRAM:
LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 1), memory->iwram); LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram); STORE_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
break; break;
case REGION_IO: case REGION_IO:
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch32: 0x%08X", address); GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch32: 0x%08X", address);
break; break;
case REGION_PALETTE_RAM: case REGION_PALETTE_RAM:
LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); STORE_32(value, address & (SIZE_PALETTE_RAM - 4), 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 - 4), value);
gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16); gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16);
break; break;
case REGION_VRAM: case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_VRAM) { if ((address & 0x0001FFFF) < SIZE_VRAM) {
LOAD_32(oldValue, address & 0x0001FFFF, gba->video.renderer->vram); LOAD_32(oldValue, address & 0x0001FFFC, gba->video.renderer->vram);
STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram); STORE_32(value, address & 0x0001FFFC, gba->video.renderer->vram);
} else { } else {
LOAD_32(oldValue, address & 0x00017FFF, gba->video.renderer->vram); LOAD_32(oldValue, address & 0x00017FFC, gba->video.renderer->vram);
STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram); STORE_32(value, address & 0x00017FFC, gba->video.renderer->vram);
} }
break; break;
case REGION_OAM: case REGION_OAM:
LOAD_32(oldValue, address & (SIZE_OAM - 1), gba->video.oam.raw); LOAD_32(oldValue, address & (SIZE_OAM - 4), gba->video.oam.raw);
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 - 1)) >> 1); gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 1)) + 2) >> 1); gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) + 2) >> 1);
break; break;
case REGION_CART0: case REGION_CART0:
case REGION_CART0_EX: 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:
case REGION_CART2_EX: case REGION_CART2_EX:
_pristineCow(gba); _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; gba->memory.romSize = (address & (SIZE_CART0 - 4)) + 4;
} }
LOAD_32(oldValue, address & (SIZE_CART0 - 1), gba->memory.rom); LOAD_32(oldValue, address & (SIZE_CART0 - 4), gba->memory.rom);
STORE_32(value, address & (SIZE_CART0 - 1), gba->memory.rom); STORE_32(value, address & (SIZE_CART0 - 4), gba->memory.rom);
break; break;
case REGION_CART_SRAM: case REGION_CART_SRAM:
case REGION_CART_SRAM_MIRROR: case REGION_CART_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) { if (memory->savedata.type == SAVEDATA_SRAM) {
LOAD_32(oldValue, 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 - 1), memory->savedata.data); STORE_32(value, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
} else { } else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address); 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) { switch (address >> BASE_OFFSET) {
case REGION_WORKING_RAM: case REGION_WORKING_RAM:
LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 1), memory->wram); LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 2), memory->wram);
STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram); STORE_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
break; break;
case REGION_WORKING_IRAM: case REGION_WORKING_IRAM:
LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 1), memory->iwram); LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram); STORE_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
break; break;
case REGION_IO: case REGION_IO:
GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch16: 0x%08X", address); GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch16: 0x%08X", address);
break; break;
case REGION_PALETTE_RAM: case REGION_PALETTE_RAM:
LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
STORE_16(value, address & (SIZE_PALETTE_RAM - 1), 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 - 1), value); gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
break; break;
case REGION_VRAM: case REGION_VRAM:
if ((address & 0x0001FFFF) < SIZE_VRAM) { if ((address & 0x0001FFFF) < SIZE_VRAM) {
LOAD_16(oldValue, address & 0x0001FFFF, gba->video.renderer->vram); LOAD_16(oldValue, address & 0x0001FFFE, gba->video.renderer->vram);
STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram); STORE_16(value, address & 0x0001FFFE, gba->video.renderer->vram);
} else { } else {
LOAD_16(oldValue, address & 0x00017FFF, gba->video.renderer->vram); LOAD_16(oldValue, address & 0x00017FFE, gba->video.renderer->vram);
STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram); STORE_16(value, address & 0x00017FFE, gba->video.renderer->vram);
} }
break; break;
case REGION_OAM: case REGION_OAM:
LOAD_16(oldValue, address & (SIZE_OAM - 1), gba->video.oam.raw); LOAD_16(oldValue, address & (SIZE_OAM - 2), gba->video.oam.raw);
STORE_16(value, address & (SIZE_OAM - 1), 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 - 1)) >> 1); gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
break; break;
case REGION_CART0: case REGION_CART0:
case REGION_CART0_EX: 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) { if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2; gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2;
} }
LOAD_16(oldValue, address & (SIZE_CART0 - 1), gba->memory.rom); LOAD_16(oldValue, address & (SIZE_CART0 - 2), gba->memory.rom);
STORE_16(value, address & (SIZE_CART0 - 1), gba->memory.rom); STORE_16(value, address & (SIZE_CART0 - 2), gba->memory.rom);
break; break;
case REGION_CART_SRAM: case REGION_CART_SRAM:
case REGION_CART_SRAM_MIRROR: case REGION_CART_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) { if (memory->savedata.type == SAVEDATA_SRAM) {
LOAD_16(oldValue, 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 - 1), memory->savedata.data); STORE_16(value, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
} else { } else {
GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address); 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_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * (GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? width >> 1 : 0x80) + (localY & 0x7) * 4;
#define SPRITE_DRAW_PIXEL_16_NORMAL(localX) \ #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; \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
current = renderer->spriteLayer[outX]; \ current = renderer->spriteLayer[outX]; \
if ((current & FLAG_ORDER_MASK) > flags) { \ if ((current & FLAG_ORDER_MASK) > flags) { \
@ -1735,7 +1735,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
} }
#define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \ #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; \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
if (tileData) { \ if (tileData) { \
renderer->row[outX] |= FLAG_OBJWIN; \ 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_YBASE_256(localY) unsigned yBase = (localY & ~0x7) * (GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? width : 0x80) + (localY & 0x7) * 8;
#define SPRITE_DRAW_PIXEL_256_NORMAL(localX) \ #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; \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
current = renderer->spriteLayer[outX]; \ current = renderer->spriteLayer[outX]; \
if ((current & FLAG_ORDER_MASK) > flags) { \ if ((current & FLAG_ORDER_MASK) > flags) { \
@ -1757,7 +1757,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
} }
#define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \ #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; \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
if (tileData) { \ if (tileData) { \
renderer->row[outX] |= FLAG_OBJWIN; \ renderer->row[outX] |= FLAG_OBJWIN; \