GBA:Fix a few memory read/write issues

- Affects both aligned and unaligned in unsigned 8/16/32 and signed 16
  reads/writes
- Rom out-of-bounds reads
- SRAM r/w access
- etc
This commit is contained in:
negativeExponent 2021-05-21 14:50:20 +08:00
parent 4e5b61f220
commit 025f3079b1
2 changed files with 17 additions and 30 deletions

View File

@ -1506,7 +1506,7 @@ int CPULoadRom(const char* szFile)
uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1)); uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1));
int i; int i;
for (i = (romSize + 1) & ~1; i < romSize; i += 2) { for (i = (romSize + 1) & ~1; i < SIZE_ROM; i += 2) {
WRITE16LE(temp, (i >> 1) & 0xFFFF); WRITE16LE(temp, (i >> 1) & 0xFFFF);
temp++; temp++;
} }
@ -1599,7 +1599,7 @@ int CPULoadRomData(const char* data, int size)
uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1)); uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1));
int i; int i;
for (i = (romSize + 1) & ~1; i < romSize; i += 2) { for (i = (romSize + 1) & ~1; i < SIZE_ROM; i += 2) {
WRITE16LE(temp, (i >> 1) & 0xFFFF); WRITE16LE(temp, (i >> 1) & 0xFFFF);
temp++; temp++;
} }

View File

@ -57,11 +57,6 @@ static inline uint32_t CPUReadMemory(uint32_t address)
} }
#endif #endif
uint32_t value = 0; uint32_t value = 0;
uint32_t oldAddress = address;
if (address & 3) {
address &= ~0x03;
}
switch (address >> 24) { switch (address >> 24) {
case 0: case 0:
@ -149,17 +144,17 @@ static inline uint32_t CPUReadMemory(uint32_t address)
value = cpuDmaLast; value = cpuDmaLast;
} else { } else {
if (armState) { if (armState) {
return CPUReadMemoryQuick(reg[15].I); value = CPUReadMemoryQuick(reg[15].I);
} else { } else {
return CPUReadHalfWordQuick(reg[15].I) | CPUReadHalfWordQuick(reg[15].I) << 16; value = CPUReadHalfWordQuick(reg[15].I) | CPUReadHalfWordQuick(reg[15].I) << 16;
} }
} }
break; break;
} }
if (oldAddress & 3) { if (address & 3) {
#ifdef C_CORE #ifdef C_CORE
int shift = (oldAddress & 3) << 3; int shift = (address & 3) << 3;
value = (value >> shift) | (value << (32 - shift)); value = (value >> shift) | (value << (32 - shift));
#else #else
#ifdef __GNUC__ #ifdef __GNUC__
@ -167,10 +162,10 @@ static inline uint32_t CPUReadMemory(uint32_t address)
"shl $3 ,%%ecx;" "shl $3 ,%%ecx;"
"ror %%cl, %0" "ror %%cl, %0"
: "=r"(value) : "=r"(value)
: "r"(value), "c"(oldAddress)); : "r"(value), "c"(address));
#else #else
__asm { __asm {
mov ecx, oldAddress; mov ecx, address;
and ecx, 3; and ecx, 3;
shl ecx, 3; shl ecx, 3;
ror [dword ptr value], cl; ror [dword ptr value], cl;
@ -180,10 +175,10 @@ static inline uint32_t CPUReadMemory(uint32_t address)
} }
#ifdef GBA_LOGGING #ifdef GBA_LOGGING
if (oldAddress & 3) { if (address & 3) {
if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned word read from: %08x at %08x (%08x)\n", log("Unaligned word read from: %08x at %08x (%08x)\n",
oldAddress, address,
armMode ? armNextPC - 4 : armNextPC - 2, armMode ? armNextPC - 4 : armNextPC - 2,
value); value);
} }
@ -203,12 +198,7 @@ static inline uint32_t CPUReadHalfWord(uint32_t address)
} }
#endif #endif
uint32_t value; uint32_t value = 0;
uint32_t oldAddress = address;
if (address & 1) {
address &= ~0x01;
}
switch (address >> 24) { switch (address >> 24) {
case 0: case 0:
@ -217,7 +207,7 @@ static inline uint32_t CPUReadHalfWord(uint32_t address)
#ifdef GBA_LOGGING #ifdef GBA_LOGGING
if (systemVerbose & VERBOSE_ILLEGAL_READ) { if (systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal halfword read from bios: %08x at %08x\n", log("Illegal halfword read from bios: %08x at %08x\n",
oldAddress, address,
armMode ? armNextPC - 4 : armNextPC - 2); armMode ? armNextPC - 4 : armNextPC - 2);
} }
#endif #endif
@ -304,20 +294,20 @@ static inline uint32_t CPUReadHalfWord(uint32_t address)
#ifdef GBA_LOGGING #ifdef GBA_LOGGING
if (systemVerbose & VERBOSE_ILLEGAL_READ) { if (systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal halfword read: %08x at %08x (%08x)\n", log("Illegal halfword read: %08x at %08x (%08x)\n",
oldAddress, address,
reg[15].I, reg[15].I,
value); value);
} }
#endif #endif
return value; break;
} }
if (oldAddress & 1) { if (address & 1) {
value = (value >> 8) | (value << 24); value = (value >> 8) | (value << 24);
#ifdef GBA_LOGGING #ifdef GBA_LOGGING
if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned halfword read from: %08x at %08x (%08x)\n", log("Unaligned halfword read from: %08x at %08x (%08x)\n",
oldAddress, address,
armMode ? armNextPC - 4 : armNextPC - 2, armMode ? armNextPC - 4 : armNextPC - 2,
value); value);
} }
@ -339,6 +329,7 @@ static inline int16_t CPUReadHalfWordSigned(uint32_t address)
value); value);
} }
#endif #endif
return (int8_t)value;
} }
return (int16_t)value; return (int16_t)value;
} }
@ -459,8 +450,6 @@ static inline void CPUWriteMemory(uint32_t address, uint32_t value)
} }
#endif #endif
address &= 0xFFFFFFFC;
switch (address >> 24) { switch (address >> 24) {
case 0x02: case 0x02:
#ifdef BKPT_SUPPORT #ifdef BKPT_SUPPORT
@ -565,8 +554,6 @@ static inline void CPUWriteHalfWord(uint32_t address, uint16_t value)
} }
#endif #endif
address &= 0xFFFFFFFE;
switch (address >> 24) { switch (address >> 24) {
case 2: case 2:
#ifdef BKPT_SUPPORT #ifdef BKPT_SUPPORT