fix sd commands 0x40 and 0x41. thanks to tueidj for the test.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7126 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
af139f4661
commit
b8e6ea14e1
|
@ -133,20 +133,30 @@ void Shutdown()
|
||||||
|
|
||||||
void SetDefaultContentFile(const std::string& _rFilename)
|
void SetDefaultContentFile(const std::string& _rFilename)
|
||||||
{
|
{
|
||||||
CWII_IPC_HLE_Device_es* pDevice = (CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
|
CWII_IPC_HLE_Device_es* pDevice =
|
||||||
|
(CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
pDevice->LoadWAD(_rFilename);
|
pDevice->LoadWAD(_rFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ES_DIVerify(u8 *_pTMD, u32 _sz)
|
void ES_DIVerify(u8 *_pTMD, u32 _sz)
|
||||||
{
|
{
|
||||||
CWII_IPC_HLE_Device_es* pDevice = (CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
|
CWII_IPC_HLE_Device_es* pDevice =
|
||||||
|
(CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
pDevice->ES_DIVerify(_pTMD, _sz);
|
pDevice->ES_DIVerify(_pTMD, _sz);
|
||||||
else
|
else
|
||||||
ERROR_LOG(WII_IPC_ES, "DIVerify called but /dev/es is not available");
|
ERROR_LOG(WII_IPC_ES, "DIVerify called but /dev/es is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDIO_EventNotify()
|
||||||
|
{
|
||||||
|
CWII_IPC_HLE_Device_sdio_slot0 *pDevice =
|
||||||
|
(CWII_IPC_HLE_Device_sdio_slot0*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/sdio/slot0")));
|
||||||
|
if (pDevice)
|
||||||
|
pDevice->EventNotify();
|
||||||
|
}
|
||||||
|
|
||||||
int GetDeviceIDByName(const std::string& _rDeviceName)
|
int GetDeviceIDByName(const std::string& _rDeviceName)
|
||||||
{
|
{
|
||||||
TDeviceMap::const_iterator itr = g_DeviceMap.begin();
|
TDeviceMap::const_iterator itr = g_DeviceMap.begin();
|
||||||
|
|
|
@ -44,6 +44,8 @@ void DoState(PointerWrap &p);
|
||||||
void SetDefaultContentFile(const std::string& _rFilename);
|
void SetDefaultContentFile(const std::string& _rFilename);
|
||||||
void ES_DIVerify(u8 *_pTMD, u32 _sz);
|
void ES_DIVerify(u8 *_pTMD, u32 _sz);
|
||||||
|
|
||||||
|
void SDIO_EventNotify();
|
||||||
|
|
||||||
int GetDeviceIDByName(const std::string& _rDeviceName);
|
int GetDeviceIDByName(const std::string& _rDeviceName);
|
||||||
|
|
||||||
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
|
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "SDCardUtil.h"
|
#include "SDCardUtil.h"
|
||||||
|
|
||||||
|
#include "WII_IPC_HLE.h"
|
||||||
#include "WII_IPC_HLE_Device_sdio_slot0.h"
|
#include "WII_IPC_HLE_Device_sdio_slot0.h"
|
||||||
|
|
||||||
#include "../HW/CPU.h"
|
#include "../HW/CPU.h"
|
||||||
|
@ -43,6 +44,18 @@ CWII_IPC_HLE_Device_sdio_slot0::~CWII_IPC_HLE_Device_sdio_slot0()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWII_IPC_HLE_Device_sdio_slot0::EventNotify()
|
||||||
|
{
|
||||||
|
if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) ||
|
||||||
|
(!SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_REMOVE))
|
||||||
|
{
|
||||||
|
Memory::Write_U32(m_event.type, m_event.addr + 4);
|
||||||
|
WII_IPC_HLE_Interface::EnqReply(m_event.addr);
|
||||||
|
m_event.addr = 0;
|
||||||
|
m_event.type = EVENT_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
|
bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_SD, "Open");
|
INFO_LOG(WII_IPC_SD, "Open");
|
||||||
|
@ -159,10 +172,8 @@ bool CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_SENDCMD:
|
case IOCTL_SENDCMD:
|
||||||
if (Memory::Read_U32(BufferIn) != SDHC_CAPABILITIES)
|
INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x ipc:%08x",
|
||||||
{
|
Memory::Read_U32(BufferIn), _CommandAddress);
|
||||||
INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD 0x%08x", Memory::Read_U32(BufferIn));
|
|
||||||
}
|
|
||||||
ReturnValue = ExecuteCommand(BufferIn, BufferInSize, 0, 0, BufferOut, BufferOutSize);
|
ReturnValue = ExecuteCommand(BufferIn, BufferInSize, 0, 0, BufferOut, BufferOutSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -172,7 +183,7 @@ bool CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress)
|
||||||
else
|
else
|
||||||
m_Status = CARD_NOT_EXIST;
|
m_Status = CARD_NOT_EXIST;
|
||||||
INFO_LOG(WII_IPC_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s",
|
INFO_LOG(WII_IPC_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s",
|
||||||
(m_Status & CARD_INSERTED) ? "inserted" : "not exitsting",
|
(m_Status & CARD_INSERTED) ? "inserted" : "not present",
|
||||||
(m_Status & CARD_INITIALIZED) ? " and initialized" : "");
|
(m_Status & CARD_INITIALIZED) ? " and initialized" : "");
|
||||||
Memory::Write_U32(m_Status, BufferOut);
|
Memory::Write_U32(m_Status, BufferOut);
|
||||||
break;
|
break;
|
||||||
|
@ -192,9 +203,32 @@ bool CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress)
|
||||||
// INFO_LOG(WII_IPC_SD, "OutBuffer");
|
// INFO_LOG(WII_IPC_SD, "OutBuffer");
|
||||||
// DumpCommands(BufferOut, BufferOutSize/4, LogTypes::WII_IPC_SD);
|
// DumpCommands(BufferOut, BufferOutSize/4, LogTypes::WII_IPC_SD);
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
if (ReturnValue == RET_EVENT_REGISTER)
|
||||||
|
{
|
||||||
return true;
|
// async
|
||||||
|
m_event.addr = _CommandAddress;
|
||||||
|
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||||
|
// Check if the condition is already true
|
||||||
|
EventNotify();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ReturnValue == RET_EVENT_UNREGISTER)
|
||||||
|
{
|
||||||
|
// release returns 0
|
||||||
|
// unknown sd int
|
||||||
|
// technically we do it out of order, oh well
|
||||||
|
Memory::Write_U32(EVENT_INVALID, m_event.addr + 4);
|
||||||
|
WII_IPC_HLE_Interface::EnqReply(m_event.addr);
|
||||||
|
m_event.addr = 0;
|
||||||
|
m_event.type = EVENT_NONE;
|
||||||
|
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress)
|
bool CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress)
|
||||||
|
@ -264,7 +298,7 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
// Note: req.addr is the virtual address of _rwBuffer
|
// Note: req.addr is the virtual address of _rwBuffer
|
||||||
|
|
||||||
|
|
||||||
u32 rwFail = 0;
|
u32 ret = RET_OK;
|
||||||
|
|
||||||
switch (req.command)
|
switch (req.command)
|
||||||
{
|
{
|
||||||
|
@ -365,7 +399,7 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
"read %lx, error %i, eof? %i",
|
"read %lx, error %i, eof? %i",
|
||||||
(unsigned long)nRead,
|
(unsigned long)nRead,
|
||||||
ferror(m_Card), feof(m_Card));
|
ferror(m_Card), feof(m_Card));
|
||||||
rwFail = 1;
|
ret = RET_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
@ -402,7 +436,7 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
"wrote %lx, error %i, eof? %i",
|
"wrote %lx, error %i, eof? %i",
|
||||||
(unsigned long)nWritten,
|
(unsigned long)nWritten,
|
||||||
ferror(m_Card), feof(m_Card));
|
ferror(m_Card), feof(m_Card));
|
||||||
rwFail = 1;
|
ret = RET_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
@ -411,23 +445,16 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
Memory::Write_U32(0x900, _BufferOut);
|
Memory::Write_U32(0x900, _BufferOut);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDHC_CAPABILITIES:
|
case EVENT_REGISTER: // async
|
||||||
{
|
DEBUG_LOG(WII_IPC_SD, "Register event %x", req.arg);
|
||||||
DEBUG_LOG(WII_IPC_SD, "SDHC_CAPABILITIES");
|
m_event.type = (EventType)req.arg;
|
||||||
// SDHC 1.0 supports only 10-63 MHz.
|
ret = RET_EVENT_REGISTER;
|
||||||
// So of course we reply 63MHz :)
|
break;
|
||||||
u32 freq = (63 << 8) + (1 << 7) + 63;
|
|
||||||
// Only support 3.3V
|
|
||||||
u32 voltage = 1 << 24;
|
|
||||||
// High Speed support
|
|
||||||
u32 speed = 1 << 21;
|
|
||||||
u32 caps = freq | voltage | speed;
|
|
||||||
Memory::Write_U32(caps, _BufferOut);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CRAZY_BIGN65:
|
case EVENT_UNREGISTER: // synchronous
|
||||||
// Just means unmount/detach, but we don't care
|
DEBUG_LOG(WII_IPC_SD, "Unregister event %x", req.arg);
|
||||||
|
m_event.type = (EventType)req.arg;
|
||||||
|
ret = RET_EVENT_UNREGISTER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -435,5 +462,5 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rwFail;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ public:
|
||||||
bool IOCtl(u32 _CommandAddress);
|
bool IOCtl(u32 _CommandAddress);
|
||||||
bool IOCtlV(u32 _CommandAddress);
|
bool IOCtlV(u32 _CommandAddress);
|
||||||
|
|
||||||
|
void EventNotify();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -67,6 +69,15 @@ private:
|
||||||
IOCTLV_SENDCMD = 0x07,
|
IOCTLV_SENDCMD = 0x07,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ExecuteCommand
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RET_OK,
|
||||||
|
RET_FAIL,
|
||||||
|
RET_EVENT_REGISTER, // internal state only - not actually returned
|
||||||
|
RET_EVENT_UNREGISTER
|
||||||
|
};
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -95,10 +106,30 @@ private:
|
||||||
ACMD_SENDOPCOND = 0x29,
|
ACMD_SENDOPCOND = 0x29,
|
||||||
ACMD_SENDSCR = 0x33,
|
ACMD_SENDSCR = 0x33,
|
||||||
|
|
||||||
SDHC_CAPABILITIES = 0x40,
|
EVENT_REGISTER = 0x40,
|
||||||
CRAZY_BIGN65 = 0x41,
|
EVENT_UNREGISTER = 0x41,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EventType
|
||||||
|
{
|
||||||
|
EVENT_NONE = 0,
|
||||||
|
EVENT_INSERT,
|
||||||
|
EVENT_REMOVE,
|
||||||
|
// from unregister, i think it is just meant to be invalid
|
||||||
|
EVENT_INVALID = 0xc210000
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO do we need more than one?
|
||||||
|
struct Event
|
||||||
|
{
|
||||||
|
EventType type;
|
||||||
|
u32 addr;
|
||||||
|
Event()
|
||||||
|
: type(EVENT_NONE)
|
||||||
|
, addr()
|
||||||
|
{}
|
||||||
|
} m_event;
|
||||||
|
|
||||||
u32 m_Status;
|
u32 m_Status;
|
||||||
u32 m_BlockLength;
|
u32 m_BlockLength;
|
||||||
u32 m_BusWidth;
|
u32 m_BusWidth;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "HW/SI.h"
|
#include "HW/SI.h"
|
||||||
#include "HW/DSPHLE/DSPHLE.h"
|
#include "HW/DSPHLE/DSPHLE.h"
|
||||||
#include "HW/DSPLLE/DSPLLE.h"
|
#include "HW/DSPLLE/DSPLLE.h"
|
||||||
|
#include "IPC_HLE/WII_IPC_HLE.h"
|
||||||
|
|
||||||
#include "Globals.h" // Local
|
#include "Globals.h" // Local
|
||||||
#include "ConfigMain.h"
|
#include "ConfigMain.h"
|
||||||
|
@ -1268,6 +1269,7 @@ void CConfigMain::WiiSettingsChanged(wxCommandEvent& event)
|
||||||
// Wii - Devices
|
// Wii - Devices
|
||||||
case ID_WII_SD_CARD:
|
case ID_WII_SD_CARD:
|
||||||
SConfig::GetInstance().m_WiiSDCard = WiiSDCard->IsChecked();
|
SConfig::GetInstance().m_WiiSDCard = WiiSDCard->IsChecked();
|
||||||
|
WII_IPC_HLE_Interface::SDIO_EventNotify();
|
||||||
break;
|
break;
|
||||||
case ID_WII_KEYBOARD:
|
case ID_WII_KEYBOARD:
|
||||||
SConfig::GetInstance().m_WiiKeyboard = WiiKeyboard->IsChecked();
|
SConfig::GetInstance().m_WiiKeyboard = WiiKeyboard->IsChecked();
|
||||||
|
|
|
@ -1,146 +1,135 @@
|
||||||
// Thanks to:
|
// SD card insertion/removal callback demo
|
||||||
// SD Card Directory Listing Demo
|
|
||||||
// Updated 12/19/2008 by PunMaster
|
|
||||||
|
|
||||||
#include <gccore.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ogcsys.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <gccore.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#include <fat.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <debug.h>
|
#define IOCTL_SDIO_SENDCMD 0x07
|
||||||
#include <math.h>
|
|
||||||
|
#define SDIO_CMD_REGINTR 0x40
|
||||||
|
#define SDIO_CMD_UNREGINTR 0x41
|
||||||
|
|
||||||
|
#define SD_INSERT_EVENT 0x01
|
||||||
|
#define SD_REMOVE_EVENT 0x02
|
||||||
|
|
||||||
|
static struct _sdiorequest
|
||||||
|
{
|
||||||
|
u32 cmd;
|
||||||
|
u32 cmd_type;
|
||||||
|
u32 rsp_type;
|
||||||
|
u32 arg;
|
||||||
|
u32 blk_cnt;
|
||||||
|
u32 blk_size;
|
||||||
|
void *dma_addr;
|
||||||
|
u32 isdma;
|
||||||
|
u32 pad0;
|
||||||
|
} sd_req;
|
||||||
|
|
||||||
|
static struct _sdioresponse
|
||||||
|
{
|
||||||
|
u32 rsp_fields[3];
|
||||||
|
u32 acmd12_response;
|
||||||
|
} sd_resp;
|
||||||
|
|
||||||
|
static s32 __sd0_fd = -1;
|
||||||
|
static const char _sd0_fs[] ATTRIBUTE_ALIGN(32) = "/dev/sdio/slot0";
|
||||||
|
|
||||||
|
static s32 __sdio_getinterrupt(u32 hook, ipccallback cb)
|
||||||
|
{
|
||||||
|
memset(&sd_req, 0, sizeof(sd_req));
|
||||||
|
|
||||||
|
sd_req.cmd = SDIO_CMD_REGINTR;
|
||||||
|
sd_req.arg = hook;
|
||||||
|
|
||||||
|
if (hook==SD_INSERT_EVENT)
|
||||||
|
printf("Requesting insert event %p %p\n", cb, &sd_resp);
|
||||||
|
else if (hook==SD_REMOVE_EVENT)
|
||||||
|
printf("Requesting removal event %p %p\n", cb, &sd_resp);
|
||||||
|
else
|
||||||
|
printf("I don't know what I'm requesting here: hook=%u\n", hook);
|
||||||
|
|
||||||
|
if (__sd0_fd<0)
|
||||||
|
__sd0_fd = IOS_Open(_sd0_fs,1);
|
||||||
|
|
||||||
|
if (__sd0_fd>=0)
|
||||||
|
return IOS_IoctlAsync(__sd0_fd,IOCTL_SDIO_SENDCMD,&sd_req,sizeof(sd_req),&sd_resp,sizeof(sd_resp),cb,NULL);
|
||||||
|
|
||||||
|
// else return the IOS_Open error code
|
||||||
|
return __sd0_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 __sdio_releaseinterrupt(void)
|
||||||
|
{
|
||||||
|
if (__sd0_fd<0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// this command makes the IOS_IoctlAsync call above return a response immediately
|
||||||
|
|
||||||
|
// sd_req.arg is already set to the right value (1 or 2, whatever was used last)
|
||||||
|
sd_req.cmd = SDIO_CMD_UNREGINTR;
|
||||||
|
return IOS_Ioctl(__sd0_fd,IOCTL_SDIO_SENDCMD,&sd_req,sizeof(sd_req),&sd_resp,sizeof(sd_resp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sd_cb(u32 ret, void* unused)
|
||||||
|
{
|
||||||
|
printf("Got an SD interrupt, ret = %08X\n", ret);
|
||||||
|
printf("Response data: %08X %08X %08X %08X\n", sd_resp.rsp_fields[0], sd_resp.rsp_fields[1], sd_resp.rsp_fields[2], sd_resp.acmd12_response);
|
||||||
|
|
||||||
|
if (ret==SD_INSERT_EVENT)
|
||||||
|
{
|
||||||
|
printf("SD card was inserted\n");
|
||||||
|
// tell us when it gets removed
|
||||||
|
__sdio_getinterrupt(SD_REMOVE_EVENT, (ipccallback)sd_cb);
|
||||||
|
}
|
||||||
|
else if (ret==SD_REMOVE_EVENT)
|
||||||
|
{
|
||||||
|
printf("SD card was removed\n");
|
||||||
|
// tell us when something is inserted
|
||||||
|
__sdio_getinterrupt(SD_INSERT_EVENT, (ipccallback)sd_cb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Unknown SD int: %08X\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void *xfb = NULL;
|
static void *xfb = NULL;
|
||||||
|
static GXRModeObj *rmode = NULL;
|
||||||
|
|
||||||
u32 first_frame = 1;
|
int main(int argc, char **argv) {
|
||||||
GXRModeObj *rmode;
|
VIDEO_Init();
|
||||||
|
WPAD_Init();
|
||||||
|
rmode = VIDEO_GetPreferredMode(NULL);
|
||||||
|
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
|
||||||
|
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
|
||||||
|
VIDEO_Configure(rmode);
|
||||||
|
VIDEO_SetNextFramebuffer(xfb);
|
||||||
|
VIDEO_SetBlack(FALSE);
|
||||||
|
VIDEO_Flush();
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||||
|
|
||||||
void Initialise()
|
printf("\x1b[2;0H");
|
||||||
{
|
printf("SD Card insertion/removal demo\n");
|
||||||
// Initialise the video system
|
printf("Press HOME at any time to exit\n");
|
||||||
VIDEO_Init();
|
|
||||||
|
|
||||||
// This function initialises the attached controllers
|
__sdio_getinterrupt(SD_INSERT_EVENT, (ipccallback)sd_cb);
|
||||||
PAD_Init();
|
|
||||||
WPAD_Init();
|
|
||||||
|
|
||||||
// Obtain the preferred video mode from the system
|
while(1) {
|
||||||
// This will correspond to the settings in the Wii menu
|
WPAD_ScanPads();
|
||||||
rmode = VIDEO_GetPreferredMode(NULL);
|
u32 pressed = WPAD_ButtonsDown(0);
|
||||||
|
if ( pressed & WPAD_BUTTON_HOME ) break;
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate memory for the display in the uncached region
|
printf("SD event release returned %d\n", __sdio_releaseinterrupt());
|
||||||
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
|
IOS_Close(__sd0_fd);
|
||||||
|
|
||||||
// Initialise the console, required for printf
|
sleep(4);
|
||||||
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
|
|
||||||
|
|
||||||
// Set up the video registers with the chosen mode
|
return 0;
|
||||||
VIDEO_Configure(rmode);
|
|
||||||
|
|
||||||
// Tell the video hardware where our display memory is
|
|
||||||
VIDEO_SetNextFramebuffer(xfb);
|
|
||||||
|
|
||||||
// Make the display visible
|
|
||||||
VIDEO_SetBlack(FALSE);
|
|
||||||
|
|
||||||
// Flush the video register changes to the hardware
|
|
||||||
VIDEO_Flush();
|
|
||||||
|
|
||||||
// Wait for Video setup to complete
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dirlist(char* path)
|
|
||||||
{
|
|
||||||
DIR* pdir = opendir(path);
|
|
||||||
|
|
||||||
if (pdir != NULL)
|
|
||||||
{
|
|
||||||
u32 sentinel = 0;
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
struct dirent* pent = readdir(pdir);
|
|
||||||
if(pent == NULL) break;
|
|
||||||
|
|
||||||
if(strcmp(".", pent->d_name) != 0 && strcmp("..", pent->d_name) != 0)
|
|
||||||
{
|
|
||||||
char dnbuf[260];
|
|
||||||
sprintf(dnbuf, "%s/%s", path, pent->d_name);
|
|
||||||
|
|
||||||
struct stat statbuf;
|
|
||||||
stat(dnbuf, &statbuf);
|
|
||||||
|
|
||||||
if(S_ISDIR(statbuf.st_mode))
|
|
||||||
{
|
|
||||||
printf("%s <DIR>\n", dnbuf);
|
|
||||||
dirlist(dnbuf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("%s (%d)\n", dnbuf, (int)statbuf.st_size);
|
|
||||||
}
|
|
||||||
sentinel++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sentinel == 0)
|
|
||||||
printf("empty\n");
|
|
||||||
|
|
||||||
closedir(pdir);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("opendir() failure.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool canList = false;
|
|
||||||
|
|
||||||
Initialise();
|
|
||||||
|
|
||||||
printf("\x1b[10;0H");
|
|
||||||
|
|
||||||
if(fatInitDefault())
|
|
||||||
{
|
|
||||||
printf("\nPress A to list dirs\n");
|
|
||||||
canList = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("\nfatInitDefault() failure.\n");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
// Call WPAD_ScanPads each loop, this reads the latest controller states
|
|
||||||
PAD_ScanPads();
|
|
||||||
WPAD_ScanPads();
|
|
||||||
|
|
||||||
// WPAD_ButtonsDown tells us which buttons were wpressed in this loop
|
|
||||||
// this is a "one shot" state which will not fire again until the button has been released
|
|
||||||
u32 pressed = PAD_ButtonsDown(0);
|
|
||||||
u32 wpressed = WPAD_ButtonsDown(0);
|
|
||||||
|
|
||||||
if ((wpressed & WPAD_BUTTON_A || pressed & PAD_BUTTON_A) && canList)
|
|
||||||
dirlist("/");
|
|
||||||
|
|
||||||
// We return to the launcher application via exit
|
|
||||||
if (wpressed & WPAD_BUTTON_HOME || pressed & PAD_BUTTON_START)
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
// Wait for the next frame
|
|
||||||
VIDEO_WaitVSync();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue