diff options
-rw-r--r-- | src/DSi_AES.cpp | 12 | ||||
-rw-r--r-- | src/DSi_I2C.cpp | 16 | ||||
-rw-r--r-- | src/DSi_NWifi.cpp | 10 | ||||
-rw-r--r-- | src/DSi_SD.cpp | 398 | ||||
-rw-r--r-- | src/DSi_SD.h | 18 |
5 files changed, 253 insertions, 201 deletions
diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index 7aae8f3..4cb1169 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -213,12 +213,12 @@ u32 ReadCnt() ret |= InputFIFO->Level(); ret |= (OutputFIFO->Level() << 5); -//printf("READ AES CNT: %08X, LEVELS: IN=%d OUT=%d\n", ret, InputFIFO->Level(), OutputFIFO->Level()); + return ret; } void WriteCnt(u32 val) -{printf("AES CNT = %08X\n", val); +{ u32 oldcnt = Cnt; Cnt = val & 0xFC1FF000; @@ -294,12 +294,12 @@ void WriteCnt(u32 val) } } - printf("AES CNT: %08X / mode=%d key=%d inDMA=%d outDMA=%d blocks=%d\n", - val, AESMode, (val >> 26) & 0x3, InputDMASize, OutputDMASize, RemBlocks); + //printf("AES CNT: %08X / mode=%d key=%d inDMA=%d outDMA=%d blocks=%d\n", + // val, AESMode, (val >> 26) & 0x3, InputDMASize, OutputDMASize, RemBlocks); } void WriteBlkCnt(u32 val) -{printf("AES BLOCK CNT %08X / %d\n", val, val>>16); +{ BlkCnt = val; } @@ -405,7 +405,7 @@ void Update() // CHECKME Cnt &= ~(1<<21); } -printf("AES: FINISHED\n"); + Cnt &= ~(1<<31); if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES); DSi::StopNDMAs(1, 0x2A); diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index b2ca6e4..9984f5e 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -84,7 +84,7 @@ u8 Read(bool last) return 0; } - printf("BPTWL: read %02X -> %02X\n", CurPos, Registers[CurPos]); + //printf("BPTWL: read %02X -> %02X\n", CurPos, Registers[CurPos]); return Registers[CurPos++]; } @@ -124,7 +124,7 @@ void Write(u8 val, bool last) Registers[CurPos] = val; } - printf("BPTWL: write %02X -> %02X\n", CurPos, val); + //printf("BPTWL: write %02X -> %02X\n", CurPos, val); CurPos++; // CHECKME } @@ -166,7 +166,7 @@ void Reset() void WriteCnt(u8 val) { - printf("I2C: write CNT %02X, %08X\n", val, NDS::GetPC(1)); + //printf("I2C: write CNT %02X, %08X\n", val, NDS::GetPC(1)); // TODO: check ACK flag // TODO: transfer delay @@ -193,7 +193,7 @@ void WriteCnt(u8 val) break; } - printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); + //printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); } else { @@ -204,7 +204,7 @@ void WriteCnt(u8 val) if (val & (1<<1)) { Device = Data & 0xFE; - printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device); + //printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device); switch (Device) { @@ -219,7 +219,7 @@ void WriteCnt(u8 val) } else { - printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); + //printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); switch (Device) { @@ -243,12 +243,12 @@ void WriteCnt(u8 val) } u8 ReadData() -{printf("I2C: read data: %02X\n", Data); +{ return Data; } void WriteData(u8 val) -{printf("I2C: write data: %02X\n", val); +{ Data = val; } diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 013173f..79bc632 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -515,6 +515,12 @@ void DSi_NWifi::SendCMD(u8 cmd, u32 param) { switch (cmd) { + case 12: + // stop command + // CHECKME: does the SDIO controller actually send those?? + // DSi firmware sets it to send them + return; + case 52: // IO_RW_DIRECT { u32 func = (param >> 28) & 0x7; @@ -608,7 +614,7 @@ void DSi_NWifi::ReadBlock() TransferAddr &= 0x1FFFF; // checkme } } - len = Host->SendData(data, len); + len = Host->DataRX(data, len); if (RemSize > 0) { @@ -628,7 +634,7 @@ void DSi_NWifi::WriteBlock() len = Host->GetTransferrableLen(len); u8 data[0x200]; - if (len = Host->ReceiveData(data, len)) + if (len = Host->DataTX(data, len)) { for (u32 i = 0; i < len; i++) { diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index a45a8ce..5231b99 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -24,7 +24,27 @@ #include "Platform.h" -#define SD_DESC (Num?"SDIO":"SD/MMC") +// observed IRQ behavior during transfers +// +// during reads: +// * bit23 is cleared during the first block, always set otherwise. weird +// * bit24 (RXRDY) gets set when the FIFO is full +// +// during reads with FIFO32: +// * FIFO16 drains directly into FIFO32 +// * when bit24 is set, FIFO32 is already full (with contents from the other FIFO) +// * reading from an empty FIFO just wraps around (and sets bit21) +// * FIFO32 starts filling when bit24 would be set? +// +// +// TX: +// * when sending command, if current FIFO full +// * upon ContinueTransfer(), if current FIFO full +// * -> upon DataTX() if current FIFO full +// * when filling FIFO + + +#define SD_DESC Num?"SDIO":"SD/MMC" DSi_SDHost::DSi_SDHost(u32 num) @@ -33,6 +53,7 @@ DSi_SDHost::DSi_SDHost(u32 num) DataFIFO[0] = new FIFO<u16>(0x100); DataFIFO[1] = new FIFO<u16>(0x100); + DataFIFO32 = new FIFO<u32>(0x80); Ports[0] = NULL; Ports[1] = NULL; @@ -42,6 +63,7 @@ DSi_SDHost::~DSi_SDHost() { delete DataFIFO[0]; delete DataFIFO[1]; + delete DataFIFO32; if (Ports[0]) delete Ports[0]; if (Ports[1]) delete Ports[1]; @@ -69,6 +91,7 @@ void DSi_SDHost::Reset() DataFIFO[0]->Clear(); DataFIFO[1]->Clear(); CurFIFO = 0; + DataFIFO32->Clear(); IRQStatus = 0; IRQMask = 0x8B7F031D; @@ -84,6 +107,8 @@ void DSi_SDHost::Reset() BlockLen16 = 0; BlockLen32 = 0; StopAction = 0; + TXReq = false; + if (Ports[0]) delete Ports[0]; if (Ports[1]) delete Ports[1]; Ports[0] = NULL; @@ -125,8 +150,8 @@ void DSi_SDHost::UpdateData32IRQ() oldflags &= (Data32IRQ >> 11); Data32IRQ &= ~0x0300; - if (IRQStatus & (1<<24)) Data32IRQ |= (1<<8); - if (!(IRQStatus & (1<<25))) Data32IRQ |= (1<<9); + if (DataFIFO32->Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8); + if (!DataFIFO32->IsEmpty()) Data32IRQ |= (1<<9); u32 newflags = ((Data32IRQ >> 8) & 0x1) | (((~Data32IRQ) >> 8) & 0x2); newflags &= (Data32IRQ >> 11); @@ -138,8 +163,6 @@ void DSi_SDHost::UpdateData32IRQ() void DSi_SDHost::ClearIRQ(u32 irq) { IRQStatus &= ~(1<<irq); - - if (irq == 24 || irq == 25) UpdateData32IRQ(); } void DSi_SDHost::SetIRQ(u32 irq) @@ -151,8 +174,6 @@ void DSi_SDHost::SetIRQ(u32 irq) if ((oldflags == 0) && (newflags != 0)) NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); - - if (irq == 24 || irq == 25) UpdateData32IRQ(); } void DSi_SDHost::UpdateIRQ(u32 oldmask) @@ -193,28 +214,20 @@ void DSi_SDHost::SendResponse(u32 val, bool last) if (last) SetIRQ(0); } -void DSi_SDHost::FinishSend(u32 param) +void DSi_SDHost::FinishRX(u32 param) { DSi_SDHost* host = (param & 0x1) ? DSi::SDIO : DSi::SDMMC; - host->CurFIFO ^= 1; + host->CheckSwapFIFO(); - host->ClearIRQ(25); - host->SetIRQ(24); - //if (param & 0x2) host->SetIRQ(2); - - // TODO: this is an assumption and should eventually be confirmed - // Flipnote sets DMA blocklen to 128 words and totallen to 1024 words - // so, presumably, DMA should trigger when the FIFO is full - // 'full' being when it reaches whatever BlockLen16 is set to, or the - // other blocklen register, or when it is actually full (but that makes - // less sense) - DSi::CheckNDMAs(1, host->Num ? 0x29 : 0x28); + if (host->DataMode == 1) + host->UpdateFIFO32(); + else + host->SetIRQ(24); } -u32 DSi_SDHost::SendData(u8* data, u32 len) +u32 DSi_SDHost::DataRX(u8* data, u32 len) { - //printf("%s: data RX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask); if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; } bool last = (BlockCountInternal == 0); @@ -232,52 +245,112 @@ u32 DSi_SDHost::SendData(u8* data, u32 len) // send-command function starts polling IRQ status u32 param = Num | (last << 1); NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, - false, 512, FinishSend, param); + false, 512, FinishRX, param); return len; } -void DSi_SDHost::FinishReceive(u32 param) +void DSi_SDHost::FinishTX(u32 param) { DSi_SDHost* host = (param & 0x1) ? DSi::SDIO : DSi::SDMMC; DSi_SDDevice* dev = host->Ports[host->PortSelect & 0x1]; - host->ClearIRQ(24); - host->SetIRQ(25); + if (host->BlockCountInternal == 0) + { + if (host->StopAction & (1<<8)) + { + if (dev) dev->SendCMD(12, 0); + } - if (dev) dev->ContinueTransfer(); + // CHECKME: presumably IRQ2 should not trigger here, but rather + // when the data transfer is done + //SetIRQ(0); + host->SetIRQ(2); + host->TXReq = false; + } + else + { + if (dev) dev->ContinueTransfer(); + } } -u32 DSi_SDHost::ReceiveData(u8* data, u32 len) +u32 DSi_SDHost::DataTX(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"); len = BlockLen16; } + TXReq = true; u32 f = CurFIFO; - if ((DataFIFO[f]->Level() << 1) < len) + + if (DataMode == 1) { - printf("%s: FIFO not full enough for a transfer (%d / %d)\n", SD_DESC, DataFIFO[f]->Level()<<1, len); - return 0; + if ((DataFIFO32->Level() << 2) < len) + { + if (DataFIFO32->IsEmpty()) + { + SetIRQ(25); + DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); + } + return 0; + } + + // drain FIFO32 into FIFO16 + + if (!DataFIFO[f]->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n"); + for (;;) + { + u32 f = CurFIFO; + if ((DataFIFO[f]->Level() << 1) >= BlockLen16) break; + if (DataFIFO32->IsEmpty()) break; + + u32 val = DataFIFO32->Read(); + DataFIFO[f]->Write(val & 0xFFFF); + DataFIFO[f]->Write(val >> 16); + } + + UpdateData32IRQ(); + + if (BlockCount32 > 1) + BlockCount32--; + } + else + { + if ((DataFIFO[f]->Level() << 1) < len) + { + if (DataFIFO[f]->IsEmpty()) SetIRQ(25); + return 0; + } } - DSi_SDDevice* dev = Ports[PortSelect & 0x1]; for (u32 i = 0; i < len; i += 2) *(u16*)&data[i] = DataFIFO[f]->Read(); CurFIFO ^= 1; + BlockCountInternal--; + + NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + false, 512, FinishTX, Num); + + return len; +} + +u32 DSi_SDHost::GetTransferrableLen(u32 len) +{ + if (len > BlockLen16) len = BlockLen16; // checkme + return len; +} + +void DSi_SDHost::CheckRX() +{ + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; + + CheckSwapFIFO(); if (BlockCountInternal <= 1) { - printf("%s: data TX complete", SD_DESC); - if (StopAction & (1<<8)) { - printf(", sending CMD12"); if (dev) dev->SendCMD(12, 0); } - printf("\n"); - // CHECKME: presumably IRQ2 should not trigger here, but rather // when the data transfer is done //SetIRQ(0); @@ -286,22 +359,34 @@ u32 DSi_SDHost::ReceiveData(u8* data, u32 len) else { BlockCountInternal--; - } - return len; + if (dev) dev->ContinueTransfer(); + } } -u32 DSi_SDHost::GetTransferrableLen(u32 len) +void DSi_SDHost::CheckTX() { - if (len > BlockLen16) len = BlockLen16; // checkme - return len; + if (!TXReq) return; + + if (DataMode == 1) + { + if ((DataFIFO32->Level() << 2) < BlockLen32) + return; + } + else + { + u32 f = CurFIFO; + if ((DataFIFO[f]->Level() << 1) < BlockLen16) + return; + } + + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; + if (dev) dev->ContinueTransfer(); } u16 DSi_SDHost::Read(u32 addr) { - if(!Num)printf("SDMMC READ %08X %08X\n", addr, NDS::GetPC(1)); - switch (addr & 0x1FF) { case 0x000: return Command; @@ -353,53 +438,7 @@ u16 DSi_SDHost::Read(u32 addr) case 0x036: return CardIRQStatus; case 0x038: return CardIRQMask; - case 0x030: // FIFO16 - { - // TODO: decrement BlockLen???? - - u32 f = CurFIFO; - if (DataFIFO[f]->IsEmpty()) - { - // TODO - return 0; - } - - DSi_SDDevice* dev = Ports[PortSelect & 0x1]; - u16 ret = DataFIFO[f]->Read(); - - if (DataFIFO[f]->IsEmpty()) - { - ClearIRQ(24); - - if (BlockCountInternal <= 1) - { - printf("%s: data RX complete", SD_DESC); - - if (StopAction & (1<<8)) - { - printf(", sending CMD12"); - if (dev) dev->SendCMD(12, 0); - } - - printf("\n"); - - // CHECKME: presumably IRQ2 should not trigger here, but rather - // when the data transfer is done - //SetIRQ(0); - SetIRQ(2); - } - else - { - BlockCountInternal--; - - if (dev) dev->ContinueTransfer(); - } - - SetIRQ(25); - } - - return ret; - } + case 0x030: return ReadFIFO16(); case 0x0D8: return DataCtl; @@ -414,61 +453,52 @@ u16 DSi_SDHost::Read(u32 addr) return 0; } -u32 DSi_SDHost::ReadFIFO32() +u16 DSi_SDHost::ReadFIFO16() { - if (DataMode != 1) return 0; - - // TODO: decrement BlockLen???? - u32 f = CurFIFO; if (DataFIFO[f]->IsEmpty()) { // TODO + // on hardware it seems to wrap around. underflow bit is set upon the first 'empty' read. return 0; } DSi_SDDevice* dev = Ports[PortSelect & 0x1]; - u32 ret = DataFIFO[f]->Read(); - ret |= (DataFIFO[f]->Read() << 16); + u16 ret = DataFIFO[f]->Read(); if (DataFIFO[f]->IsEmpty()) { - ClearIRQ(24); - - if (BlockCountInternal <= 1) - { - printf("%s: data32 RX complete", SD_DESC); + CheckRX(); + } - if (StopAction & (1<<8)) - { - printf(", sending CMD12"); - if (dev) dev->SendCMD(12, 0); - } + return ret; +} - printf("\n"); +u32 DSi_SDHost::ReadFIFO32() +{ + if (DataMode != 1) return 0; - // CHECKME: presumably IRQ2 should not trigger here, but rather - // when the data transfer is done - //SetIRQ(0); - SetIRQ(2); - } - else - { - BlockCountInternal--; + if (DataFIFO32->IsEmpty()) + { + // TODO + return 0; + } - if (dev) dev->ContinueTransfer(); - } + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; + u32 ret = DataFIFO32->Read(); - SetIRQ(25); + if (DataFIFO32->IsEmpty()) + { + CheckRX(); } + UpdateData32IRQ(); + return ret; } void DSi_SDHost::Write(u32 addr, u16 val) { - if(!Num)printf("SDMMC WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1)); - switch (addr & 0x1FF) { case 0x000: @@ -528,36 +558,10 @@ 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 (16) 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 0x030: WriteFIFO16(val); return; case 0x034: CardIRQCtl = val & 0x0305; - printf("[%d] CardIRQCtl = %04X\n", Num, val); SetCardIRQ(); return; case 0x036: @@ -565,7 +569,6 @@ void DSi_SDHost::Write(u32 addr, u16 val) return; case 0x038: CardIRQMask = val & 0xC007; - printf("[%d] CardIRQMask = %04X\n", Num, val); SetCardIRQ(); return; @@ -593,12 +596,7 @@ void DSi_SDHost::Write(u32 addr, u16 val) case 0x100: Data32IRQ = (val & 0x1802) | (Data32IRQ & 0x0300); - if (val & (1<<10)) - { - // kind of hacky - u32 f = CurFIFO; - DataFIFO[f]->Clear(); - } + if (val & (1<<10)) DataFIFO32->Clear(); DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1); printf("%s: data mode %d-bit\n", SD_DESC, DataMode?32:16); return; @@ -609,35 +607,76 @@ void DSi_SDHost::Write(u32 addr, u16 val) printf("unknown %s write %08X %04X\n", SD_DESC, addr, val); } -void DSi_SDHost::WriteFIFO32(u32 val) +void DSi_SDHost::WriteFIFO16(u16 val) { - if (DataMode != 1) return; - - printf("%s: WRITE FIFO32: LEVEL=%d/%d\n", SD_DESC, DataFIFO[CurFIFO]->Level(), (BlockLen16>>1)); - DSi_SDDevice* dev = Ports[PortSelect & 0x1]; u32 f = CurFIFO; if (DataFIFO[f]->IsFull()) { // TODO - printf("!!!! %s FIFO (32) FULL\n", SD_DESC); + printf("!!!! %s FIFO (16) FULL\n", SD_DESC); return; } - DataFIFO[f]->Write(val & 0xFFFF); - DataFIFO[f]->Write(val >> 16); + DataFIFO[f]->Write(val); + + CheckTX(); +} + +void DSi_SDHost::WriteFIFO32(u32 val) +{ + if (DataMode != 1) return; - if (DataFIFO[f]->Level() < (BlockLen16>>1)) + if (DataFIFO32->IsFull()) { - ClearIRQ(25); - SetIRQ(24); + // TODO + printf("!!!! %s FIFO (32) FULL\n", SD_DESC); 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); + DataFIFO32->Write(val); + + CheckTX(); + + UpdateData32IRQ(); +} + +void DSi_SDHost::UpdateFIFO32() +{ + // check whether we can drain FIFO32 into FIFO16, or vice versa + + if (DataMode != 1) return; + + if (!DataFIFO32->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n"); + for (;;) + { + u32 f = CurFIFO; + if ((DataFIFO32->Level() << 2) >= BlockLen32) break; + if (DataFIFO[f]->IsEmpty()) break; + + u32 val = DataFIFO[f]->Read(); + val |= (DataFIFO[f]->Read() << 16); + DataFIFO32->Write(val); + } + + UpdateData32IRQ(); + + if ((DataFIFO32->Level() << 2) >= BlockLen32) + { + DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); + } +} + +void DSi_SDHost::CheckSwapFIFO() +{ + // check whether we can swap the FIFOs + + u32 f = CurFIFO; + bool cur_empty = (DataMode == 1) ? DataFIFO32->IsEmpty() : DataFIFO[f]->IsEmpty(); + if (cur_empty && ((DataFIFO[f^1]->Level() << 1) >= BlockLen16)) + { + CurFIFO ^= 1; + } } @@ -813,7 +852,7 @@ void DSi_MMCStorage::SendACMD(u8 cmd, u32 param) case 13: // get SSR Host->SendResponse(CSR, true); - Host->SendData(SSR, 64); + Host->DataRX(SSR, 64); return; case 41: // set operating conditions @@ -834,7 +873,7 @@ void DSi_MMCStorage::SendACMD(u8 cmd, u32 param) case 51: // get SCR Host->SendResponse(CSR, true); - Host->SendData(SCR, 8); + Host->DataRX(SCR, 8); return; } @@ -863,8 +902,6 @@ void DSi_MMCStorage::ContinueTransfer() u32 DSi_MMCStorage::ReadBlock(u64 addr) { - //printf("SD/MMC: reading block @ %08X, len=%08X\n", addr, BlockSize); - u32 len = BlockSize; len = Host->GetTransferrableLen(len); @@ -874,18 +911,17 @@ u32 DSi_MMCStorage::ReadBlock(u64 addr) fseek(File, addr, SEEK_SET); fread(data, 1, len, File); } - return Host->SendData(data, len); + + return Host->DataRX(data, len); } u32 DSi_MMCStorage::WriteBlock(u64 addr) { - printf("SD/MMC: write block @ %08X, len=%08X\n", addr, BlockSize); - u32 len = BlockSize; len = Host->GetTransferrableLen(len); u8 data[0x200]; - if (len = Host->ReceiveData(data, len)) + if (len = Host->DataTX(data, len)) { if (File) { diff --git a/src/DSi_SD.h b/src/DSi_SD.h index f4ca26c..2862173 100644 --- a/src/DSi_SD.h +++ b/src/DSi_SD.h @@ -36,20 +36,29 @@ public: void DoSavestate(Savestate* file); - static void FinishSend(u32 param); - static void FinishReceive(u32 param); + static void FinishRX(u32 param); + static void FinishTX(u32 param); void SendResponse(u32 val, bool last); - u32 SendData(u8* data, u32 len); - u32 ReceiveData(u8* data, u32 len); + u32 DataRX(u8* data, u32 len); + u32 DataTX(u8* data, u32 len); u32 GetTransferrableLen(u32 len); + void CheckRX(); + void CheckTX(); + bool TXReq; + void SetCardIRQ(); u16 Read(u32 addr); void Write(u32 addr, u16 val); + u16 ReadFIFO16(); + void WriteFIFO16(u16 val); u32 ReadFIFO32(); void WriteFIFO32(u32 val); + void UpdateFIFO32(); + void CheckSwapFIFO(); + private: u32 Num; @@ -78,6 +87,7 @@ private: FIFO<u16>* DataFIFO[2]; u32 CurFIFO; // FIFO accessible for read/write + FIFO<u32>* DataFIFO32; DSi_SDDevice* Ports[2]; |