moar SD/MMC commands

This commit is contained in:
Arisotura
2019-06-17 18:40:45 +02:00
parent bedc0220fc
commit 6c75275593
4 changed files with 100 additions and 14 deletions

View File

@ -52,6 +52,7 @@ void DSi_SDHost::Reset()
}
SoftReset = 0x0007; // CHECKME
SDClock = 0;
Command = 0;
Param = 0;
@ -67,8 +68,11 @@ void DSi_SDHost::Reset()
if (Num == 0)
{
DSi_MMCStorage* mmc = new DSi_MMCStorage(this, true, "nand.bin");
mmc->SetCID(DSi::eMMC_CID);
// TODO: port 0 (SD)
Ports[1] = new DSi_MMCStorage(this, true, "nand.bin");
Ports[1] = mmc;
}
else
{
@ -129,6 +133,8 @@ u16 DSi_SDHost::Read(u32 addr)
case 0x020: return IRQMask & 0x031D;
case 0x022: return (IRQMask >> 16) & 0x8B7F;
case 0x024: return SDClock;
case 0x0E0: return SoftReset;
}
@ -150,10 +156,13 @@ void DSi_SDHost::Write(u32 addr, u16 val)
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
if (dev)
{
// CHECKME
// "Setting Command Type to "ACMD" is automatically sending an APP_CMD prefix prior to the command number"
// except DSi boot2 manually sends an APP_CMD prefix AND sets the next command to be ACMD
switch ((Command >> 6) & 0x3)
{
case 0: dev->SendCMD(cmd, Param); break;
case 1: dev->SendACMD(cmd, Param); break;
case 1: /*dev->SendCMD(55, 0);*/ dev->SendCMD(cmd, Param); break;
default:
printf("%s: unknown command type %d, %02X %08X\n", SD_DESC, (Command>>6)&0x3, cmd, Param);
break;
@ -171,6 +180,8 @@ void DSi_SDHost::Write(u32 addr, u16 val)
case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return;
case 0x022: IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); return;
case 0x024: SDClock = val & 0x03FF; return;
case 0x0E0:
if ((SoftReset & 0x0001) && !(val & 0x0001))
{
@ -200,6 +211,14 @@ DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path
File = Platform::OpenLocalFile(path, "r+b");
CSR = 0x00; // checkme
// TODO: busy bit
// TODO: SDHC/SDXC bit
OCR = 0x80FF8000;
// TODO: customize based on card size etc
u8 csd_template[16] = {0x40, 0x40, 0x96, 0xE9, 0x7F, 0xDB, 0xF6, 0xDF, 0x01, 0x59, 0x0F, 0x2A, 0x01, 0x26, 0x90, 0x00};
memcpy(CSD, csd_template, 16);
}
DSi_MMCStorage::~DSi_MMCStorage()
@ -209,21 +228,76 @@ DSi_MMCStorage::~DSi_MMCStorage()
void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
{
if (CSR & (1<<5))
{
CSR &= ~(1<<5);
return SendACMD(cmd, param);
}
switch (cmd)
{
case 0x00: // reset/etc
case 0: // reset/etc
Host->SendResponse(CSR, true);
return;
case 0x08: // set voltage
case 2:
case 10: // get CID
Host->SendResponse(*(u32*)&CID[0], false);
Host->SendResponse(*(u32*)&CID[1], false);
Host->SendResponse(*(u32*)&CID[2], false);
Host->SendResponse(*(u32*)&CID[3], true);
//if (cmd == 2) SetState(0x02);
return;
case 3: // get/set RCA
if (Internal)
{
RCA = param >> 16;
Host->SendResponse(CSR|0x10000, true); // huh??
}
else
{
// TODO
printf("CMD3 on SD card: TODO\n");
}
return;
case 7: // select card (by RCA)
Host->SendResponse(CSR, true);
return;
case 8: // set voltage
Host->SendResponse(param, true);
return;
case 9: // get CSD
Host->SendResponse(*(u32*)&CSD[0], false);
Host->SendResponse(*(u32*)&CSD[1], false);
Host->SendResponse(*(u32*)&CSD[2], false);
Host->SendResponse(*(u32*)&CSD[3], true);
return;
case 55: // ??
printf("CMD55 %08X\n", param);
CSR |= (1<<5);
Host->SendResponse(CSR, true);
return;
}
printf("MMC: unknown CMD %02X %08X\n", cmd, param);
printf("MMC: unknown CMD %d %08X\n", cmd, param);
}
void DSi_MMCStorage::SendACMD(u8 cmd, u32 param)
{
printf("MMC: ACMD %02X %08X\n", cmd, param);
switch (cmd)
{
case 41: // set operating conditions
OCR &= 0xBF000000;
OCR |= (param & 0x40FFFFFF);
Host->SendResponse(OCR, true);
SetState(0x01);
return;
}
printf("MMC: unknown ACMD %d %08X\n", cmd, param);
}