aboutsummaryrefslogtreecommitdiff
path: root/src/DSi_SD.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/DSi_SD.cpp')
-rw-r--r--src/DSi_SD.cpp70
1 files changed, 54 insertions, 16 deletions
diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp
index 6e73df5..c9edd78 100644
--- a/src/DSi_SD.cpp
+++ b/src/DSi_SD.cpp
@@ -185,7 +185,8 @@ void DSi_SDHost::SendData(u8* data, u32 len)
// but if IRQ24 is thrown instantly, the handler clears IRQ0 before the
// send-command function starts polling IRQ status
u32 param = Num | (last << 1);
- NDS::ScheduleEvent(NDS::Event_DSi_SDTransfer, false, 512, FinishSend, param);
+ NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer,
+ false, 512, FinishSend, param);
}
void DSi_SDHost::FinishReceive(u32 param)
@@ -199,13 +200,19 @@ void DSi_SDHost::FinishReceive(u32 param)
if (dev) dev->ContinueTransfer();
}
-void DSi_SDHost::ReceiveData(u8* data, u32 len)
+bool DSi_SDHost::ReceiveData(u8* data, u32 len)
{
printf("%s: data TX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
if (len != BlockLen16) printf("!! BAD BLOCKLEN\n");
- DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u32 f = CurFIFO;
+ if ((DataFIFO[f]->Level() << 1) < len)
+ {
+ printf("%s: FIFO not full enough for a transfer (%d / %d)\n", SD_DESC, DataFIFO[f]->Level()<<1, len);
+ return false;
+ }
+
+ DSi_SDDevice* dev = Ports[PortSelect & 0x1];
for (u32 i = 0; i < len; i += 2)
*(u16*)&data[i] = DataFIFO[f]->Read();
@@ -213,7 +220,7 @@ void DSi_SDHost::ReceiveData(u8* data, u32 len)
if (BlockCountInternal <= 1)
{
- printf("%s: data32 TX complete", SD_DESC);
+ printf("%s: data TX complete", SD_DESC);
if (StopAction & (1<<8))
{
@@ -232,12 +239,14 @@ void DSi_SDHost::ReceiveData(u8* data, u32 len)
{
BlockCountInternal--;
}
+
+ return true;
}
u16 DSi_SDHost::Read(u32 addr)
{
- //printf("SDMMC READ %08X %08X\n", addr, NDS::GetPC(1));
+ //if(Num)printf("SDIO READ %08X %08X\n", addr, NDS::GetPC(1));
switch (addr & 0x1FF)
{
@@ -383,7 +392,7 @@ u32 DSi_SDHost::ReadFIFO32()
void DSi_SDHost::Write(u32 addr, u16 val)
{
- //printf("SDMMC WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
+ //if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
switch (addr & 0x1FF)
{
@@ -421,7 +430,11 @@ void DSi_SDHost::Write(u32 addr, u16 val)
case 0x01C: IRQStatus &= (val | 0xFFFF0000); return;
case 0x01E: IRQStatus &= ((val << 16) | 0xFFFF); return;
case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return;
- case 0x022: IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); return;
+ case 0x022:
+ IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16);
+ if (!DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(24); // checkme
+ if (DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(25); // checkme
+ return;
case 0x024: SDClock = val & 0x03FF; return;
case 0x026:
@@ -430,6 +443,33 @@ void DSi_SDHost::Write(u32 addr, u16 val)
return;
case 0x028: SDOption = val & 0xC1FF; return;
+ case 0x030: // FIFO16
+ {
+ DSi_SDDevice* dev = Ports[PortSelect & 0x1];
+ u32 f = CurFIFO;
+ if (DataFIFO[f]->IsFull())
+ {
+ // TODO
+ printf("!!!! %s FIFO FULL\n", SD_DESC);
+ return;
+ }
+
+ DataFIFO[f]->Write(val);
+
+ if (DataFIFO[f]->Level() < (BlockLen16>>1))
+ {
+ ClearIRQ(25);
+ SetIRQ(24);
+ return;
+ }
+
+ // we completed one block, send it to the SD card
+ // TODO measure the actual delay!!
+ NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer,
+ false, 2048, FinishReceive, Num);
+ }
+ return;
+
case 0x0D8:
DataCtl = (val & 0x0022);
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
@@ -494,13 +534,9 @@ void DSi_SDHost::WriteFIFO32(u32 val)
}
// we completed one block, send it to the SD card
-
- //ClearIRQ(24);
- //SetIRQ(25);
-
- //if (dev) dev->ContinueTransfer();
// TODO measure the actual delay!!
- NDS::ScheduleEvent(NDS::Event_DSi_SDTransfer, false, 2048, FinishReceive, Num);
+ NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer,
+ false, 2048, FinishReceive, Num);
}
@@ -726,7 +762,9 @@ void DSi_MMCStorage::WriteBlock(u64 addr)
printf("SD/MMC: write block @ %08X, len=%08X\n", addr, BlockSize);
u8 data[0x200];
- Host->ReceiveData(data, BlockSize);
- fseek(File, addr, SEEK_SET);
- fwrite(data, 1, BlockSize, File);
+ if (Host->ReceiveData(data, BlockSize))
+ {
+ fseek(File, addr, SEEK_SET);
+ fwrite(data, 1, BlockSize, File);
+ }
}