Skip to content

Commit 8ba0c5a

Browse files
Revised gpio/eeprom/backup save checks / logic / range
- fixes proper detection of save types or attached gpio device - really need a proper and deterministic way to detect and set all these instead of waiting for core to present. too many enabled AUTO for example
1 parent d6d5d95 commit 8ba0c5a

File tree

2 files changed

+92
-44
lines changed

2 files changed

+92
-44
lines changed

src/core/gba/gbaInline.h

Lines changed: 84 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,31 @@ static inline uint16_t ROMReadOOB(uint32_t address) {
123123
return (address >> 1) & 0xFFFF;
124124
}
125125

126+
static inline bool IsGPIO(uint32_t address) {
127+
// TODO: Need to check which GPIO feature really is enabled
128+
return (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8);
129+
}
130+
131+
// used for ROM boundary check
132+
static inline bool IsEEPROM(uint32_t address) {
133+
return (cpuEEPROMEnabled && (address & eepromMask) == eepromMask);
134+
}
135+
136+
static inline bool isSaveGame() {
137+
return (coreOptions.saveType != 5) && (!eepromInUse || cpuSramEnabled || cpuFlashEnabled);
138+
}
139+
140+
// Reads sram or flash
141+
static inline uint8_t CPUReadBackup(uint32_t address) {
142+
return flashRead(address);
143+
}
144+
145+
// writes sram or flash
146+
static inline void CPUWriteBackup(uint32_t address, uint8_t value) {
147+
if (cpuSaveGameFunc)
148+
(*cpuSaveGameFunc)(address, value);
149+
}
150+
126151
static inline uint32_t CPUReadMemory(uint32_t address)
127152
{
128153
#ifdef VBAM_ENABLE_DEBUGGER
@@ -133,7 +158,7 @@ static inline uint32_t CPUReadMemory(uint32_t address)
133158
}
134159
}
135160
#endif
136-
uint32_t value = 0xFFFFFFFF;
161+
uint32_t value = 0;
137162

138163
switch (address >> 24) {
139164
case REGION_BIOS:
@@ -194,27 +219,34 @@ static inline uint32_t CPUReadMemory(uint32_t address)
194219
case REGION_ROM1:
195220
case REGION_ROM1EX:
196221
case REGION_ROM2:
197-
if ((address & 0x01FFFFFC) <= (gbaGetRomSize() - 4))
222+
if (IsEEPROM(address))
223+
return 0; // ignore reads from eeprom region outside 0x0D page reads
224+
else if ((address & 0x01FFFFFC) <= (gbaGetRomSize() - 4))
198225
value = READ32LE(((uint32_t *)&g_rom[address & 0x01FFFFFC]));
199-
else if (cpuEEPROMEnabled && ((address & eepromMask) == eepromMask))
200-
return 0; // ignore reads from eeprom region outside 0x0D page reads
201226
else {
202227
value = (uint16_t)ROMReadOOB(address & 0x01FFFFFC);
203228
value |= (uint16_t)ROMReadOOB((address & 0x01FFFFFC) + 2) << 16;
204229
}
205230
break;
206231
case REGION_ROM2EX:
207232
if (cpuEEPROMEnabled)
208-
// no need to swap this
209233
return eepromRead(address);
210234
goto unreadable;
211235
case REGION_SRAM:
212236
case REGION_SRAMEX:
213-
if (cpuFlashEnabled | cpuSramEnabled) { // no need to swap this
214-
value = flashRead(address) * 0x01010101;
237+
if (isSaveGame()) {
238+
value = CPUReadBackup(address) * 0x01010101;
215239
break;
216240
}
217-
/* fallthrough */
241+
#ifdef GBA_LOGGING
242+
// Just normal log, not openbus
243+
if (systemVerbose & VERBOSE_ILLEGAL_READ) {
244+
log("Illegal word read: %08x at %08x\n",
245+
address,
246+
armMode ? armNextPC - 4 : armNextPC - 2);
247+
}
248+
#endif
249+
return 0xffffffff;
218250
default:
219251
unreadable:
220252
#ifdef GBA_LOGGING
@@ -274,7 +306,7 @@ static inline uint32_t CPUReadHalfWord(uint32_t address)
274306
}
275307
#endif
276308

277-
uint32_t value = 0xFFFFFFFF;
309+
uint32_t value = 0;
278310

279311
switch (address >> 24) {
280312
case REGION_BIOS:
@@ -349,28 +381,35 @@ static inline uint32_t CPUReadHalfWord(uint32_t address)
349381
case REGION_ROM1:
350382
case REGION_ROM1EX:
351383
case REGION_ROM2:
352-
if ((address & 0x01FFFFFE) <= (gbaGetRomSize() - 2))
353-
value = READ16LE(((uint16_t *)&g_rom[address & 0x01FFFFFE]));
354-
else if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
384+
if (IsGPIO(address))
355385
value = rtcRead(address);
356-
else if (cpuEEPROMEnabled && ((address & eepromMask) == eepromMask))
386+
else if (IsEEPROM(address))
357387
return 0; // ignore reads from eeprom region outside 0x0D page reads
388+
else if ((address & 0x01FFFFFE) <= (gbaGetRomSize() - 2))
389+
value = READ16LE(((uint16_t *)&g_rom[address & 0x01FFFFFE]));
358390
else
359391
value = (uint16_t)ROMReadOOB(address & 0x01FFFFFE);
360392
break;
361393
case REGION_ROM2EX:
362394
if (cpuEEPROMEnabled)
363-
// no need to swap this
364395
return eepromRead(address);
365396
goto unreadable;
366397
case REGION_SRAM:
367398
case REGION_SRAMEX:
368-
if (cpuFlashEnabled | cpuSramEnabled) {
369-
// no need to swap this
370-
value = flashRead(address) * 0x0101;
399+
if (isSaveGame()) {
400+
value = CPUReadBackup(address) * 0x0101;
371401
break;
372402
}
373-
/* fallthrough */
403+
#ifdef GBA_LOGGING
404+
// Just normal log, not openbus
405+
if (systemVerbose & VERBOSE_ILLEGAL_READ) {
406+
log("Illegal halfword read: %08x at %08x (%08x)\n",
407+
address,
408+
reg[15].I,
409+
value);
410+
}
411+
#endif
412+
return 0xffff;
374413
default:
375414
unreadable:
376415
#ifdef GBA_LOGGING
@@ -469,20 +508,21 @@ static inline uint8_t CPUReadByte(uint32_t address)
469508
case REGION_ROM1:
470509
case REGION_ROM1EX:
471510
case REGION_ROM2:
472-
if ((address & 0x01FFFFFF) <= gbaGetRomSize())
473-
return g_rom[address & 0x01FFFFFF];
474-
else if (cpuEEPROMEnabled && ((address & eepromMask) == eepromMask))
511+
if (IsEEPROM(address))
475512
return 0; // ignore reads from eeprom region outside 0x0D page reads
476-
return (uint8_t)ROMReadOOB(address & 0x01FFFFFE);
513+
else if ((address & 0x01FFFFFF) <= gbaGetRomSize())
514+
return g_rom[address & 0x01FFFFFF];
515+
else
516+
return (uint8_t)ROMReadOOB(address & 0x01FFFFFE);
477517
case REGION_ROM2EX:
478518
if (cpuEEPROMEnabled)
479519
return DowncastU8(eepromRead(address));
480520
goto unreadable;
481521
case REGION_SRAM:
482522
case REGION_SRAMEX:
483-
if (cpuSramEnabled | cpuFlashEnabled)
484-
return flashRead(address);
485-
523+
if (isSaveGame()) {
524+
return CPUReadBackup(address);
525+
}
486526
switch (address & 0x00008f00) {
487527
case 0x8200:
488528
return DowncastU8(systemGetSensorX());
@@ -493,7 +533,15 @@ static inline uint8_t CPUReadByte(uint32_t address)
493533
case 0x8500:
494534
return DowncastU8(systemGetSensorY() >> 8);
495535
}
496-
return 0xFF;
536+
#ifdef GBA_LOGGING
537+
// Just normal log, not openbus
538+
if (systemVerbose & VERBOSE_ILLEGAL_READ) {
539+
log("Illegal byte read: %08x at %08x\n",
540+
address,
541+
armMode ? armNextPC - 4 : armNextPC - 2);
542+
}
543+
#endif
544+
return 0xff;
497545
default:
498546
unreadable:
499547
#ifdef GBA_LOGGING
@@ -603,12 +651,11 @@ static inline void CPUWriteMemory(uint32_t address, uint32_t value)
603651
goto unwritable;
604652
case REGION_SRAM:
605653
case REGION_SRAMEX:
606-
if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) {
607-
(*cpuSaveGameFunc)(address, (uint8_t)(value >> (8 * (address & 3))));
654+
if (isSaveGame()) {
655+
CPUWriteBackup(address, (uint8_t)(value >> (8 * (address & 3))));
608656
break;
609657
}
610-
goto unwritable;
611-
// fallthrough
658+
// fallthrough
612659
default:
613660
unwritable:
614661
#ifdef GBA_LOGGING
@@ -704,7 +751,7 @@ static inline void CPUWriteHalfWord(uint32_t address, uint16_t value)
704751
GBAMatrixWrite16(&GBAMatrix, address & 0x3C, value);
705752
break;
706753
}
707-
if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
754+
if (IsGPIO(address)) {
708755
if (!rtcWrite(address, value))
709756
goto unwritable;
710757
} else if (!agbPrintWrite(address, value))
@@ -727,11 +774,11 @@ static inline void CPUWriteHalfWord(uint32_t address, uint16_t value)
727774
goto unwritable;
728775
case REGION_SRAM:
729776
case REGION_SRAMEX:
730-
if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) {
731-
(*cpuSaveGameFunc)(address, (uint8_t)(value >> (8 * (address & 1))));
777+
if (isSaveGame()) {
778+
CPUWriteBackup(address, (uint8_t)(value >> (8 * (address & 1))));
732779
break;
733780
}
734-
/* fallthrough */
781+
// fallthrough
735782
default:
736783
unwritable:
737784
#ifdef GBA_LOGGING
@@ -867,9 +914,6 @@ static inline void CPUWriteByte(uint32_t address, uint8_t b)
867914
}
868915
break;
869916
case REGION_OAM:
870-
// no need to switch
871-
// byte writes to OAM are ignored
872-
// *((uint16_t *)&g_oam[address & 0x3FE]) = (b << 8) | b;
873917
break;
874918
case REGION_ROM2EX:
875919
if (cpuEEPROMEnabled) {
@@ -879,12 +923,11 @@ static inline void CPUWriteByte(uint32_t address, uint8_t b)
879923
goto unwritable;
880924
case REGION_SRAM:
881925
case REGION_SRAMEX:
882-
if ((coreOptions.saveType != 5) && ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)) {
883-
(*cpuSaveGameFunc)(address, b);
926+
if (isSaveGame()) {
927+
CPUWriteBackup(address, b);
884928
break;
885929
}
886-
goto unwritable;
887-
// default
930+
// fallthrough
888931
default:
889932
unwritable:
890933
#ifdef GBA_LOGGING

src/libretro/libretro.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ static void load_image_preferences(void)
840840
};
841841

842842
bool found = false;
843-
int saveType = 0;
843+
int saveType = GBA_SAVE_AUTO;
844844
int saveSize = 0;
845845
bool hasRtc = false;
846846
bool hasRumble = false;
@@ -909,7 +909,7 @@ static void load_image_preferences(void)
909909
}
910910

911911
// Autodetect save type is needed
912-
if (!saveType) {
912+
if (saveType == GBA_SAVE_AUTO) {
913913
log("Autodetecting save type...\n");
914914
// FLASH 1M Sanyo
915915
if (find_string(g_rom, romSize, "FLASH1M_"))
@@ -942,11 +942,16 @@ static void load_image_preferences(void)
942942
{
943943
log("Found SRAM_\n");
944944
saveType = GBA_SAVE_SRAM;
945+
} else
946+
947+
// no save type found
948+
{
949+
saveType = GBA_SAVE_NONE;
945950
}
946951

947952
// RTC flag
948953
if (find_string(g_rom, romSize, "SIIRTC_V")) {
949-
log("Found SRAM_\n");
954+
log("Found RTC\n");
950955
hasRtc = true;
951956
}
952957
}

0 commit comments

Comments
 (0)