usbloadergx/source/usbloader/NandEmu.cpp
Cyan fa4b1d162b * Fixed missing games in "GameCube Delete menu" if
the "GameCube Source" setting has USB priority.
* Fixed Playlog writing when using Hermes cIOS v4 (untested)
  (Requires AHB access).
* Fixed EmuNAND when using cIOS revision 65535 (issue 2225)
* Added Nintendont support:
  1. Select Nintendont's boot.dol folder in userpath settings.
  2. Set the "GameCube Mode" setting to Nintendont.
  3. Nintendont share some of DIOS MIOS (Lite) settings.
* Added sections in the Loader settings  
  (Wii/gamecube/Devolution/DIOS MIOS/Nintendont).
* Updated the GameCube game settings to display only 
  the selected GameCube mode related settings.
* Updated some menus to support more controller's input:
   - Prevent GC/CC X and Y buttons to change row number in
     Wall layout (use d-pad up/down only)
   - Added GC/CC support to carousel's arrow button
   - Added GC/CC support to Wall/Carousel continuous 
     scroll (+/- on CC, L/R on GC)
   - Added GC support L/R and Start buttons in the
     settings/homebrew browser.
   - Added D-pad support in listing windows if not pointing 
     the screen. The cursor now moves with the selection 
     (not very good with high Overscan value) (issue 2093)
* Changed the StartupProcess to speed up launch time by 
  using AHB access to read config files. IOS argument in
  meta.xml has priority over AHB detection.
* Added IOS58 + AHB support for launching the loader
  without cIOS (Wii games and EmuNAND still require cIOS).
* Added a Loader's IOS setting (now Loader and Games use 
  two separate settings: loader can use 58 and games 249).
* Added LibruntimeIOSPatch to patch IOS58 and Hermes v4 to
  get ISFS access and enable Banner mode, Channel's title
  and System font with these IOSes (Requires AHB access)
* Added a delete prompt if downloaded cheat file is empty.
* Force all launched homebrew to reload to IOS58 if available.
* Changed Gecko.c to send logs to wifigecko too.
* Changed wifigecko IP to send logs to all IP 192.168.0.x
* Updated French translation.
2013-10-01 21:13:08 +00:00

272 lines
4.6 KiB
C++

/*****************************************
* This code is from Mighty Channel 11
* which is based on the TriiForce source.
* Modifications by Dimok.
*****************************************/
#include <stdio.h>
#include <ogcsys.h>
#include <malloc.h>
#include <string.h>
#include "system/IosLoader.h"
#include "utils/tools.h"
#include "gecko.h"
#include "NandEmu.h"
/* 'NAND Device' structure */
typedef struct {
/* Device name */
const char *name;
/* Mode value */
u32 mode;
/* Un/mount command */
u32 mountCmd;
u32 umountCmd;
} nandDevice;
static nandDevice ndevList[] =
{
{ "Disable", 0, 0x00, 0x00 },
{ "SD/SDHC Card", 1, 0xF0, 0xF1 },
{ "USB 2.0 Mass Storage Device", 2, 0xF2, 0xF3 },
};
/* Buffer */
static const char fs[] ATTRIBUTE_ALIGN(32) = "/dev/fs";
static const char fat[] ATTRIBUTE_ALIGN(32) = "fat";
static u32 inbuf[8] ATTRIBUTE_ALIGN(32);
static u32 partition ATTRIBUTE_ALIGN(32) = 0;
static u32 mode ATTRIBUTE_ALIGN(32) = 0;
static char path[32] ATTRIBUTE_ALIGN(32) = "\0";
static int fullmode = 0;
static int mounted = 0;
static s32 Nand_Mount(nandDevice *dev)
{
s32 fd, ret;
u32 inlen = 0;
ioctlv *vector = NULL;
int rev = IOS_GetRevision();
/* Open FAT module */
fd = IOS_Open(fat, 0);
if (fd < 0)
return fd;
if(rev >= 21 && rev != 65280) // stub version from nintendo
{
// NOTE:
// The official cIOSX rev21 by Waninkoko ignores the partition argument
// and the nand is always expected to be on the 1st partition.
// However this way earlier d2x betas having revision 21 take in
// consideration the partition argument.
inlen = 1;
/* Allocate memory */
vector = (ioctlv *) memalign(32, sizeof(ioctlv));
if(vector == NULL)
{
/* Close FAT module */
IOS_Close(fd);
return -2;
}
vector[0].data = &partition;
vector[0].len = sizeof(u32);
}
/* Mount device */
ret = IOS_Ioctlv(fd, dev->mountCmd, inlen, 0, vector);
/* Close FAT module */
IOS_Close(fd);
/* Free memory */
free(vector);
return ret;
}
static s32 Nand_Unmount(nandDevice *dev)
{
s32 fd, ret;
// Open FAT module
fd = IOS_Open(fat, 0);
if (fd < 0)
return fd;
// Unmount device
ret = IOS_Ioctlv(fd, dev->umountCmd, 0, 0, NULL);
// Close FAT module
IOS_Close(fd);
return ret;
}
static s32 Nand_Enable(nandDevice *dev)
{
s32 fd, ret;
ioctlv *vector = NULL;
int rev = IOS_GetRevision();
// Open /dev/fs
fd = IOS_Open(fs, 0);
if (fd < 0)
return fd;
if (IOS_GetRevision() >= 18)
{
//FULL NAND emulation since rev18
//needed for reading images on triiforce mrc folder using ISFS commands
mode = dev->mode | fullmode;
}
else
{
mode = dev->mode;
}
if(rev >= 21 && rev != 65280) // stub version from nintendo
{
// NOTE:
// The official cIOSX rev21 by Waninkoko provides an undocumented feature
// to set nand path when mounting the device.
// This feature has been discovered during d2x development.
/* Allocate memory */
vector = (ioctlv *)memalign(32, sizeof(ioctlv)*2);
if(vector == NULL)
{
/* Close FAT module */
IOS_Close(fd);
return -2;
}
vector[0].data = &mode;
vector[0].len = sizeof(u32);
vector[1].data = path;
vector[1].len = sizeof(path);
ret = IOS_Ioctlv(fd, 100, 2, 0, vector);
/* Free memory */
free(vector);
}
else
{
memset(inbuf, 0, sizeof(inbuf));
inbuf[0] = dev->mode;
ret = IOS_Ioctl(fd, 100, inbuf, sizeof(inbuf), NULL, 0);
}
// Close /dev/fs
IOS_Close(fd);
return ret;
}
static s32 Nand_Disable(void)
{
s32 fd, ret;
// Open /dev/fs
fd = IOS_Open(fs, 0);
if (fd < 0)
return fd;
// Set input buffer
mode = 0;
// Disable NAND emulator
ret = IOS_Ioctl(fd, 100, &mode, sizeof(mode), NULL, 0);
// Close /dev/fs
IOS_Close(fd);
return ret;
}
s32 Enable_Emu(int selection)
{
if(!IosLoader::IsD2X() && IOS_GetRevision() < 17)
return -1;
if(mounted != 0)
return -1;
s32 ret;
nandDevice *ndev = NULL;
ndev = &ndevList[selection];
ret = Nand_Mount(ndev);
if (ret < 0)
{
gprintf(" ERROR Mount! (ret = %d)\n", ret);
return ret;
}
ret = Nand_Enable(ndev);
if (ret < 0)
{
gprintf(" ERROR Enable! (ret = %d)\n", ret);
return ret;
}
mounted = selection;
return 0;
}
s32 Disable_Emu()
{
if(!IosLoader::IsD2X() && IOS_GetRevision() < 17)
return -1;
if(mounted==0)
return 0;
nandDevice *ndev = NULL;
ndev = &ndevList[mounted];
Nand_Disable();
Nand_Unmount(ndev);
mounted = 0;
return 0;
}
void Set_Partition(int p)
{
partition = p;
}
void Set_Path(const char* p)
{
int i = 0;
while(p[i] != '\0' && i < 31)
{
path[i] = p[i];
i++;
}
while(path[i-1] == '/')
{
path[i-1] = '\0';
--i;
}
path[i] = '\0';
}
void Set_FullMode(int fm)
{
fullmode = fm ? 0x100 : 0;
}
const char* Get_Path(void)
{
return path;
}