aboutsummaryrefslogtreecommitdiff
path: root/src/NDSCart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/NDSCart.cpp')
-rw-r--r--src/NDSCart.cpp87
1 files changed, 43 insertions, 44 deletions
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp
index f291d7b..696666b 100644
--- a/src/NDSCart.cpp
+++ b/src/NDSCart.cpp
@@ -246,7 +246,7 @@ void Write_Discover(u8 val, bool islast)
{
Discover_MemoryType = 5;
}
- else if (len > 2+128) // Flash
+ else if ((len > 2+128) || (len > 1+16 && CurCmd == 0xA)) // Flash
{
Discover_MemoryType = 4;
}
@@ -284,7 +284,7 @@ void Write_EEPROMTiny(u8 val, bool islast)
}
else
{
- SRAM[(Addr & 0xFF) | ((CurCmd==0x0A)?0x100:0)] = val;
+ SRAM[(Addr + ((CurCmd==0x0A)?0x100:0)) & 0x1FF] = val;
Addr++;
}
break;
@@ -298,7 +298,7 @@ void Write_EEPROMTiny(u8 val, bool islast)
}
else
{
- Data = SRAM[(Addr & 0xFF) | ((CurCmd==0x0B)?0x100:0)];
+ Data = SRAM[(Addr + ((CurCmd==0x0B)?0x100:0)) & 0x1FF];
Addr++;
}
break;
@@ -471,11 +471,20 @@ void Write(u8 val, u32 hold)
switch (CurCmd)
{
+ case 0x00:
+ // Pokémon carts have an IR transceiver thing, and send this
+ // to bypass it and access SRAM.
+ // TODO: design better
+ CurCmd = val;
+ break;
+
case 0x02:
case 0x03:
case 0x0A:
case 0x0B:
case 0x9F:
+ case 0xD8:
+ case 0xDB:
WriteFunc(val, islast);
DataPos++;
break;
@@ -496,7 +505,7 @@ void Write(u8 val, u32 hold)
default:
if (DataPos==0)
- printf("unknown save SPI command %02X\n", CurCmd);
+ printf("unknown save SPI command %02X %08X\n", CurCmd);
break;
}
@@ -801,9 +810,8 @@ void ReadROM_B7(u32 addr, u32 len, u32 offset)
}
-void EndTransfer()
+void ROMEndTransfer(u32 param)
{
- ROMCnt &= ~(1<<23);
ROMCnt &= ~(1<<31);
if (SPICnt & (1<<14))
@@ -820,16 +828,16 @@ void ROMPrepareData(u32 param)
DataOutPos += 4;
ROMCnt |= (1<<23);
- NDS::CheckDMAs(0, 0x06);
- NDS::CheckDMAs(1, 0x12);
- //if (DataOutPos < DataOutLen)
- // NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0);
+ if (NDS::ExMemCnt[0] & (1<<11))
+ NDS::CheckDMAs(1, 0x12);
+ else
+ NDS::CheckDMAs(0, 0x05);
}
void WriteROMCnt(u32 val)
{
- ROMCnt = val & 0xFF7F7FFF;
+ ROMCnt = (val & 0xFF7F7FFF) | (ROMCnt & 0x00800000);
if (!(SPICnt & (1<<15))) return;
@@ -958,52 +966,43 @@ void WriteROMCnt(u32 val)
break;
}
- //ROMCnt &= ~(1<<23);
- ROMCnt |= (1<<23);
+ ROMCnt &= ~(1<<23);
+
+ // ROM transfer timings
+ // the bus is parallel with 8 bits
+ // thus a command would take 8 cycles to be transferred
+ // and it would take 4 cycles to receive a word of data
+ // TODO: advance read position if bit28 is set
+
+ u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5;
+ u32 cmddelay = 8 + (ROMCnt & 0x1FFF);
+ if (datasize) cmddelay += ((ROMCnt >> 16) & 0x3F);
if (datasize == 0)
- EndTransfer();
+ NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*cmddelay, ROMEndTransfer, 0);
else
- {
- NDS::CheckDMAs(0, 0x05);
- NDS::CheckDMAs(1, 0x12);
- }
- //NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0);
+ NDS::ScheduleEvent(NDS::Event_ROMTransfer, true, xfercycle*(cmddelay+4), ROMPrepareData, 0);
}
u32 ReadROMData()
{
- /*if (ROMCnt & (1<<23))
+ if (ROMCnt & (1<<23))
{
ROMCnt &= ~(1<<23);
- if (DataOutPos >= DataOutLen)
- EndTransfer();
- }
-
- return ROMDataOut;*/
- u32 ret;
- if (DataOutPos >= DataOutLen)
- ret = 0;
- else
- ret = *(u32*)&DataOut[DataOutPos];
-
- DataOutPos += 4;
- if (DataOutPos == DataOutLen)
- EndTransfer();
-
- return ret;
-}
+ if (DataOutPos < DataOutLen)
+ {
+ u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5;
+ u32 delay = 4;
+ if (!(DataOutPos & 0x1FF)) delay += ((ROMCnt >> 16) & 0x3F);
-void DMA(u32 addr)
-{
- void (*writefn)(u32,u32) = (NDS::ExMemCnt[0] & (1<<11)) ? NDS::ARM7Write32 : NDS::ARM9Write32;
- for (u32 i = 0; i < DataOutLen; i+=4)
- {
- writefn(addr+i, *(u32*)&DataOut[i]);
+ NDS::ScheduleEvent(NDS::Event_ROMTransfer, true, xfercycle*delay, ROMPrepareData, 0);
+ }
+ else
+ ROMEndTransfer(0);
}
- EndTransfer();
+ return ROMDataOut;
}