aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2021-05-04 12:58:59 +0200
committerArisotura <thetotalworm@gmail.com>2021-05-04 12:58:59 +0200
commit50721719d27ccdd5457d54c9df57fae24b018488 (patch)
treee9c79a87f2c71c5366dd7d2d0948fcfbc40a2502 /src
parentb7d5a7db7508dba1e1e5f527accf0dadc84efb21 (diff)
GBACart: simulate open-bus decay roughly. fixes #1093
Diffstat (limited to 'src')
-rw-r--r--src/GBACart.cpp15
-rw-r--r--src/GBACart.h2
-rw-r--r--src/NDS.cpp54
3 files changed, 42 insertions, 29 deletions
diff --git a/src/GBACart.cpp b/src/GBACart.cpp
index 808fc0b..e5b6e4f 100644
--- a/src/GBACart.cpp
+++ b/src/GBACart.cpp
@@ -40,15 +40,15 @@ const char SOLAR_SENSOR_GAMECODES[10][5] =
bool CartInserted;
-//bool HasSolarSensor;
u8* CartROM;
u32 CartROMSize;
u32 CartCRC;
u32 CartID;
-//GPIO CartGPIO; // overridden GPIO parameters
CartCommon* Cart;
+u16 OpenBusDecay;
+
CartCommon::CartCommon()
{
@@ -631,6 +631,9 @@ void Reset()
// This allows resetting a DS game without losing GBA state,
// and resetting to firmware without the slot being emptied.
// The Stop function will clear the cartridge state via Eject().
+
+ // OpenBusDecay doesn't need to be reset, either, as it will be set
+ // through NDS::SetGBASlotTimings().
}
void Eject()
@@ -795,11 +798,17 @@ int SetInput(int num, bool pressed)
}
+void SetOpenBusDecay(u16 val)
+{
+ OpenBusDecay = val;
+}
+
+
u16 ROMRead(u32 addr)
{
if (Cart) return Cart->ROMRead(addr);
- return (addr >> 1) & 0xFFFF;
+ return ((addr >> 1) & 0xFFFF) | OpenBusDecay;
}
void ROMWrite(u32 addr, u16 val)
diff --git a/src/GBACart.h b/src/GBACart.h
index 1f4d258..8698e25 100644
--- a/src/GBACart.h
+++ b/src/GBACart.h
@@ -161,6 +161,8 @@ void RelocateSave(const char* path, bool write);
// TODO: make more flexible, support nonbinary inputs
int SetInput(int num, bool pressed);
+void SetOpenBusDecay(u16 val);
+
u16 ROMRead(u32 addr);
void ROMWrite(u32 addr, u16 val);
diff --git a/src/NDS.cpp b/src/NDS.cpp
index eade479..ad96153 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -1242,33 +1242,35 @@ void SetWifiWaitCnt(u16 val)
void SetGBASlotTimings()
{
- int curcpu = (ExMemCnt[0] >> 7) & 0x1;
-
const int ntimings[4] = {10, 8, 6, 18};
+ const u16 openbus[4] = {0xFE08, 0x0000, 0x0000, 0xFFFF};
- u16 curcnt = ExMemCnt[curcpu];
- int ramN = ntimings[curcnt & 0x3];
- int romN = ntimings[(curcnt>>2) & 0x3];
- int romS = (curcnt & 0x10) ? 4 : 6;
+ u16 curcnt;
+ int ramN, romN, romS;
- // TODO: PHI pin thing?
+ curcnt = ExMemCnt[0];
+ ramN = ntimings[curcnt & 0x3];
+ romN = ntimings[(curcnt>>2) & 0x3];
+ romS = (curcnt & 0x10) ? 4 : 6;
- if (curcpu == 0)
- {
- SetARM9RegionTimings(0x08000000, 0x0A000000, 16, romN + 3, romS);
- SetARM9RegionTimings(0x0A000000, 0x0B000000, 8, ramN + 3, ramN);
+ SetARM9RegionTimings(0x08000000, 0x0A000000, 16, romN + 3, romS);
+ SetARM9RegionTimings(0x0A000000, 0x0B000000, 8, ramN + 3, ramN);
- SetARM7RegionTimings(0x08000000, 0x0A000000, 32, 1, 1);
- SetARM7RegionTimings(0x0A000000, 0x0B000000, 32, 1, 1);
- }
- else
- {
- SetARM9RegionTimings(0x08000000, 0x0A000000, 32, 1, 1);
- SetARM9RegionTimings(0x0A000000, 0x0B000000, 32, 1, 1);
+ curcnt = ExMemCnt[1];
+ ramN = ntimings[curcnt & 0x3];
+ romN = ntimings[(curcnt>>2) & 0x3];
+ romS = (curcnt & 0x10) ? 4 : 6;
- SetARM7RegionTimings(0x08000000, 0x0A000000, 16, romN, romS);
- SetARM7RegionTimings(0x0A000000, 0x0B000000, 8, ramN, ramN);
- }
+ SetARM7RegionTimings(0x08000000, 0x0A000000, 16, romN, romS);
+ SetARM7RegionTimings(0x0A000000, 0x0B000000, 8, ramN, ramN);
+
+ // this open-bus implementation is a rough way of simulating the way values
+ // lingering on the bus decay after a while, which is visible at higher waitstates
+ // for example, the Cartridge Construction Kit relies on this to determine that
+ // the GBA slot is empty
+
+ curcnt = ExMemCnt[(ExMemCnt[0]>>7) & 0x1];
+ GBACart::SetOpenBusDecay(openbus[(curcnt>>2) & 0x3]);
}
@@ -1863,8 +1865,8 @@ void debug(u32 param)
//for (int i = 0; i < 9; i++)
// printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
- /*FILE*
- shit = fopen("debug/party.bin", "wb");
+ FILE*
+ shit = fopen("debug/construct.bin", "wb");
fwrite(ARM9->ITCM, 0x8000, 1, shit);
for (u32 i = 0x02000000; i < 0x02400000; i+=4)
{
@@ -1876,9 +1878,9 @@ void debug(u32 param)
u32 val = ARM7Read32(i);
fwrite(&val, 4, 1, shit);
}
- fclose(shit);*/
+ fclose(shit);
- FILE*
+ /*FILE*
shit = fopen("debug/power9.bin", "wb");
for (u32 i = 0x02000000; i < 0x04000000; i+=4)
{
@@ -1892,7 +1894,7 @@ void debug(u32 param)
u32 val = DSi::ARM7Read32(i);
fwrite(&val, 4, 1, shit);
}
- fclose(shit);
+ fclose(shit);*/
}