Skip to content

Commit 5996fa7

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 5996fa7

File tree

2 files changed

+93
-44
lines changed

2 files changed

+93
-44
lines changed

src/core/gba/gbaInline.h

Lines changed: 85 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,22 @@ 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+
}
526+
// this should not be needed for GBA, even so need a proper check to see if its used or enabled
486527
switch (address & 0x00008f00) {
487528
case 0x8200:
488529
return DowncastU8(systemGetSensorX());
@@ -493,7 +534,15 @@ static inline uint8_t CPUReadByte(uint32_t address)
493534
case 0x8500:
494535
return DowncastU8(systemGetSensorY() >> 8);
495536
}
496-
return 0xFF;
537+
#ifdef GBA_LOGGING
538+
// Just normal log, not openbus
539+
if (systemVerbose & VERBOSE_ILLEGAL_READ) {
540+
log("Illegal byte read: %08x at %08x\n",
541+
address,
542+
armMode ? armNextPC - 4 : armNextPC - 2);
543+
}
544+
#endif
545+
return 0xff;
497546
default:
498547
unreadable:
499548
#ifdef GBA_LOGGING
@@ -603,12 +652,11 @@ static inline void CPUWriteMemory(uint32_t address, uint32_t value)
603652
goto unwritable;
604653
case REGION_SRAM:
605654
case REGION_SRAMEX:
606-
if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) {
607-
(*cpuSaveGameFunc)(address, (uint8_t)(value >> (8 * (address & 3))));
655+
if (isSaveGame()) {
656+
CPUWriteBackup(address, (uint8_t)(value >> (8 * (address & 3))));
608657
break;
609658
}
610-
goto unwritable;
611-
// fallthrough
659+
// fallthrough
612660
default:
613661
unwritable:
614662
#ifdef GBA_LOGGING
@@ -704,7 +752,7 @@ static inline void CPUWriteHalfWord(uint32_t address, uint16_t value)
704752
GBAMatrixWrite16(&GBAMatrix, address & 0x3C, value);
705753
break;
706754
}
707-
if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
755+
if (IsGPIO(address)) {
708756
if (!rtcWrite(address, value))
709757
goto unwritable;
710758
} else if (!agbPrintWrite(address, value))
@@ -727,11 +775,11 @@ static inline void CPUWriteHalfWord(uint32_t address, uint16_t value)
727775
goto unwritable;
728776
case REGION_SRAM:
729777
case REGION_SRAMEX:
730-
if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) {
731-
(*cpuSaveGameFunc)(address, (uint8_t)(value >> (8 * (address & 1))));
778+
if (isSaveGame()) {
779+
CPUWriteBackup(address, (uint8_t)(value >> (8 * (address & 1))));
732780
break;
733781
}
734-
/* fallthrough */
782+
// fallthrough
735783
default:
736784
unwritable:
737785
#ifdef GBA_LOGGING
@@ -867,9 +915,6 @@ static inline void CPUWriteByte(uint32_t address, uint8_t b)
867915
}
868916
break;
869917
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;
873918
break;
874919
case REGION_ROM2EX:
875920
if (cpuEEPROMEnabled) {
@@ -879,12 +924,11 @@ static inline void CPUWriteByte(uint32_t address, uint8_t b)
879924
goto unwritable;
880925
case REGION_SRAM:
881926
case REGION_SRAMEX:
882-
if ((coreOptions.saveType != 5) && ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)) {
883-
(*cpuSaveGameFunc)(address, b);
927+
if (isSaveGame()) {
928+
CPUWriteBackup(address, b);
884929
break;
885930
}
886-
goto unwritable;
887-
// default
931+
// fallthrough
888932
default:
889933
unwritable:
890934
#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)