mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
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:
@ -1,146 +1,135 @@
|
||||
// Thanks to:
|
||||
// SD Card Directory Listing Demo
|
||||
// Updated 12/19/2008 by PunMaster
|
||||
// SD card insertion/removal callback demo
|
||||
|
||||
#include <gccore.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ogcsys.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <gccore.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <fat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <debug.h>
|
||||
#include <math.h>
|
||||
|
||||
#define IOCTL_SDIO_SENDCMD 0x07
|
||||
|
||||
#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 GXRModeObj *rmode = NULL;
|
||||
|
||||
u32 first_frame = 1;
|
||||
GXRModeObj *rmode;
|
||||
int main(int argc, char **argv) {
|
||||
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()
|
||||
{
|
||||
// Initialise the video system
|
||||
VIDEO_Init();
|
||||
printf("\x1b[2;0H");
|
||||
printf("SD Card insertion/removal demo\n");
|
||||
printf("Press HOME at any time to exit\n");
|
||||
|
||||
// This function initialises the attached controllers
|
||||
PAD_Init();
|
||||
WPAD_Init();
|
||||
__sdio_getinterrupt(SD_INSERT_EVENT, (ipccallback)sd_cb);
|
||||
|
||||
// Obtain the preferred video mode from the system
|
||||
// This will correspond to the settings in the Wii menu
|
||||
rmode = VIDEO_GetPreferredMode(NULL);
|
||||
while(1) {
|
||||
WPAD_ScanPads();
|
||||
u32 pressed = WPAD_ButtonsDown(0);
|
||||
if ( pressed & WPAD_BUTTON_HOME ) break;
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
// Allocate memory for the display in the uncached region
|
||||
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
|
||||
printf("SD event release returned %d\n", __sdio_releaseinterrupt());
|
||||
IOS_Close(__sd0_fd);
|
||||
|
||||
// Initialise the console, required for printf
|
||||
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
|
||||
sleep(4);
|
||||
|
||||
// Set up the video registers with the chosen mode
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user