take this shit further
This commit is contained in:
parent
d4dd97638d
commit
bedc0220fc
|
@ -57,16 +57,16 @@ u32 NWRAMStart[2][3];
|
|||
u32 NWRAMEnd[2][3];
|
||||
u32 NWRAMMask[2][3];
|
||||
|
||||
DSi_SD* SDMMC;
|
||||
DSi_SD* SDIO;
|
||||
DSi_SDHost* SDMMC;
|
||||
DSi_SDHost* SDIO;
|
||||
|
||||
|
||||
bool Init()
|
||||
{
|
||||
if (!DSi_I2C::Init()) return false;
|
||||
|
||||
SDMMC = new DSi_SD(0);
|
||||
SDIO = new DSi_SD(1);
|
||||
SDMMC = new DSi_SDHost(0);
|
||||
SDIO = new DSi_SDHost(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
175
src/DSi_SD.cpp
175
src/DSi_SD.cpp
|
@ -20,19 +20,27 @@
|
|||
#include <string.h>
|
||||
#include "DSi.h"
|
||||
#include "DSi_SD.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
DSi_SD::DSi_SD(u32 num)
|
||||
#define SD_DESC (Num?"SDIO":"SD/MMC")
|
||||
|
||||
|
||||
DSi_SDHost::DSi_SDHost(u32 num)
|
||||
{
|
||||
Num = num;
|
||||
|
||||
Ports[0] = NULL;
|
||||
Ports[1] = NULL;
|
||||
}
|
||||
|
||||
DSi_SD::~DSi_SD()
|
||||
DSi_SDHost::~DSi_SDHost()
|
||||
{
|
||||
//
|
||||
if (Ports[0]) delete Ports[0];
|
||||
if (Ports[1]) delete Ports[1];
|
||||
}
|
||||
|
||||
void DSi_SD::Reset()
|
||||
void DSi_SDHost::Reset()
|
||||
{
|
||||
if (Num == 0)
|
||||
{
|
||||
|
@ -42,31 +50,180 @@ void DSi_SD::Reset()
|
|||
{
|
||||
PortSelect = 0x0100; // CHECKME
|
||||
}
|
||||
|
||||
SoftReset = 0x0007; // CHECKME
|
||||
|
||||
Command = 0;
|
||||
Param = 0;
|
||||
memset(ResponseBuffer, 0, sizeof(ResponseBuffer));
|
||||
|
||||
IRQStatus = 0;
|
||||
IRQMask = 0x8B7F031D;
|
||||
|
||||
if (Ports[0]) delete Ports[0];
|
||||
if (Ports[1]) delete Ports[1];
|
||||
Ports[0] = NULL;
|
||||
Ports[1] = NULL;
|
||||
|
||||
if (Num == 0)
|
||||
{
|
||||
// TODO: port 0 (SD)
|
||||
Ports[1] = new DSi_MMCStorage(this, true, "nand.bin");
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: SDIO (wifi)
|
||||
}
|
||||
}
|
||||
|
||||
void DSi_SD::DoSavestate(Savestate* file)
|
||||
void DSi_SDHost::DoSavestate(Savestate* file)
|
||||
{
|
||||
// TODO!
|
||||
}
|
||||
|
||||
|
||||
u16 DSi_SD::Read(u32 addr)
|
||||
void DSi_SDHost::SetIRQ(u32 irq)
|
||||
{
|
||||
u32 oldflags = IRQStatus & ~IRQMask;
|
||||
|
||||
IRQStatus |= (1<<irq);
|
||||
u32 newflags = IRQStatus & ~IRQMask;
|
||||
|
||||
if ((oldflags == 0) && (newflags != 0))
|
||||
NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC);
|
||||
}
|
||||
|
||||
void DSi_SDHost::SendResponse(u32 val, bool last)
|
||||
{
|
||||
*(u32*)&ResponseBuffer[6] = *(u32*)&ResponseBuffer[4];
|
||||
*(u32*)&ResponseBuffer[4] = *(u32*)&ResponseBuffer[2];
|
||||
*(u32*)&ResponseBuffer[2] = *(u32*)&ResponseBuffer[0];
|
||||
*(u32*)&ResponseBuffer[0] = val;
|
||||
|
||||
if (last) SetIRQ(0);
|
||||
}
|
||||
|
||||
|
||||
u16 DSi_SDHost::Read(u32 addr)
|
||||
{
|
||||
//printf("SDMMC READ %08X %08X\n", addr, NDS::GetPC(1));
|
||||
|
||||
switch (addr & 0x1FF)
|
||||
{
|
||||
case 0x000: return Command;
|
||||
case 0x002: return PortSelect & 0x030F;
|
||||
case 0x004: return Param & 0xFFFF;
|
||||
case 0x006: return Param >> 16;
|
||||
|
||||
case 0x00C: return ResponseBuffer[0];
|
||||
case 0x00E: return ResponseBuffer[1];
|
||||
case 0x010: return ResponseBuffer[2];
|
||||
case 0x012: return ResponseBuffer[3];
|
||||
case 0x014: return ResponseBuffer[4];
|
||||
case 0x016: return ResponseBuffer[5];
|
||||
case 0x018: return ResponseBuffer[6];
|
||||
case 0x01A: return ResponseBuffer[7];
|
||||
|
||||
case 0x01C: return IRQStatus & 0x031D;
|
||||
case 0x01E: return (IRQStatus >> 16) & 0x8B7F;
|
||||
case 0x020: return IRQMask & 0x031D;
|
||||
case 0x022: return (IRQMask >> 16) & 0x8B7F;
|
||||
|
||||
case 0x0E0: return SoftReset;
|
||||
}
|
||||
|
||||
printf("unknown %s read %08X\n", Num?"SDIO":"SD/MMC", addr);
|
||||
printf("unknown %s read %08X\n", SD_DESC, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSi_SD::Write(u32 addr, u16 val)
|
||||
void DSi_SDHost::Write(u32 addr, u16 val)
|
||||
{
|
||||
//printf("SDMMC WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
|
||||
|
||||
switch (addr & 0x1FF)
|
||||
{
|
||||
case 0x000:
|
||||
{
|
||||
Command = val;
|
||||
u8 cmd = Command & 0x3F;
|
||||
|
||||
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
||||
if (dev)
|
||||
{
|
||||
switch ((Command >> 6) & 0x3)
|
||||
{
|
||||
case 0: dev->SendCMD(cmd, Param); break;
|
||||
case 1: dev->SendACMD(cmd, Param); break;
|
||||
default:
|
||||
printf("%s: unknown command type %d, %02X %08X\n", SD_DESC, (Command>>6)&0x3, cmd, Param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x002: PortSelect = val; return;
|
||||
case 0x004: Param = (Param & 0xFFFF0000) | val; return;
|
||||
case 0x006: Param = (Param & 0x0000FFFF) | (val << 16); return;
|
||||
|
||||
case 0x01C: IRQStatus &= ~(u32)val; return;
|
||||
case 0x01E: IRQStatus &= ~((u32)val << 16); return;
|
||||
case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return;
|
||||
case 0x022: IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); return;
|
||||
|
||||
case 0x0E0:
|
||||
if ((SoftReset & 0x0001) && !(val & 0x0001))
|
||||
{
|
||||
printf("%s: RESET\n", SD_DESC);
|
||||
// TODO: STOP_INTERNAL_ACTION
|
||||
// TODO: SD_RESPONSE
|
||||
IRQStatus = 0;
|
||||
// TODO: ERROR_DETAIL_STATUS
|
||||
// TODO: CARD_CLK_CTL
|
||||
// TODO: CARD_OPTION
|
||||
// TODO: CARD_IRQ_STAT
|
||||
// TODO: FIFO16 shit
|
||||
}
|
||||
SoftReset = 0x0006 | (val & 0x0001);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("unknown %s write %08X %04X\n", Num?"SDIO":"SD/MMC", addr, val);
|
||||
printf("unknown %s write %08X %04X\n", SD_DESC, addr, val);
|
||||
}
|
||||
|
||||
|
||||
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path) : DSi_SDDevice(host)
|
||||
{
|
||||
Internal = internal;
|
||||
strncpy(FilePath, path, 1023); FilePath[1023] = '\0';
|
||||
|
||||
File = Platform::OpenLocalFile(path, "r+b");
|
||||
|
||||
CSR = 0x00; // checkme
|
||||
}
|
||||
|
||||
DSi_MMCStorage::~DSi_MMCStorage()
|
||||
{
|
||||
if (File) fclose(File);
|
||||
}
|
||||
|
||||
void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case 0x00: // reset/etc
|
||||
Host->SendResponse(CSR, true);
|
||||
return;
|
||||
|
||||
case 0x08: // set voltage
|
||||
Host->SendResponse(param, true);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("MMC: unknown CMD %02X %08X\n", cmd, param);
|
||||
}
|
||||
|
||||
void DSi_MMCStorage::SendACMD(u8 cmd, u32 param)
|
||||
{
|
||||
printf("MMC: ACMD %02X %08X\n", cmd, param);
|
||||
}
|
||||
|
|
55
src/DSi_SD.h
55
src/DSi_SD.h
|
@ -19,16 +19,21 @@
|
|||
#ifndef DSI_SD_H
|
||||
#define DSI_SD_H
|
||||
|
||||
class DSi_SD
|
||||
class DSi_SDDevice;
|
||||
|
||||
|
||||
class DSi_SDHost
|
||||
{
|
||||
public:
|
||||
DSi_SD(u32 num);
|
||||
~DSi_SD();
|
||||
DSi_SDHost(u32 num);
|
||||
~DSi_SDHost();
|
||||
|
||||
void Reset();
|
||||
|
||||
void DoSavestate(Savestate* file);
|
||||
|
||||
void SendResponse(u32 val, bool last);
|
||||
|
||||
u16 Read(u32 addr);
|
||||
void Write(u32 addr, u16 val);
|
||||
|
||||
|
@ -36,6 +41,50 @@ private:
|
|||
u32 Num;
|
||||
|
||||
u16 PortSelect;
|
||||
u16 SoftReset;
|
||||
|
||||
u32 IRQStatus; // IF
|
||||
u32 IRQMask; // ~IE
|
||||
|
||||
u16 Command;
|
||||
u32 Param;
|
||||
u16 ResponseBuffer[8];
|
||||
|
||||
DSi_SDDevice* Ports[2];
|
||||
|
||||
void SetIRQ(u32 irq);
|
||||
};
|
||||
|
||||
|
||||
class DSi_SDDevice
|
||||
{
|
||||
public:
|
||||
DSi_SDDevice(DSi_SDHost* host) { Host = host; }
|
||||
~DSi_SDDevice() {}
|
||||
|
||||
virtual void SendCMD(u8 cmd, u32 param) = 0;
|
||||
virtual void SendACMD(u8 cmd, u32 param) = 0;
|
||||
|
||||
protected:
|
||||
DSi_SDHost* Host;
|
||||
};
|
||||
|
||||
|
||||
class DSi_MMCStorage : public DSi_SDDevice
|
||||
{
|
||||
public:
|
||||
DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path);
|
||||
~DSi_MMCStorage();
|
||||
|
||||
void SendCMD(u8 cmd, u32 param);
|
||||
void SendACMD(u8 cmd, u32 param);
|
||||
|
||||
private:
|
||||
bool Internal;
|
||||
char FilePath[1024];
|
||||
FILE* File;
|
||||
|
||||
u8 CSR;
|
||||
};
|
||||
|
||||
#endif // DSI_SD_H
|
||||
|
|
Loading…
Reference in New Issue