-fixed BASIC(!) channel launching, currently only booting

channels from real nand works here, also return to wiiflow
seems to be broken, but its a start
This commit is contained in:
fix94.1 2012-05-20 12:34:48 +00:00
parent bdfe989462
commit 0c32d1b0c1
6 changed files with 92 additions and 64 deletions

View File

@ -20,6 +20,7 @@ void __Disc_SetLowMem(void);
void __Disc_SetVMode(void);
void __Disc_SetTime(void);
void _unstub_start();
u32 entryPoint;
extern void __exception_closeall();
@ -35,15 +36,10 @@ typedef struct _dolheader{
u32 padding[7];
} __attribute__((packed)) dolheader;
u32 entryPoint;
s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio)
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
{
u32 ios;
Identify(chantitle, &ios);
entryPoint = LoadChannel(data);
MEM2_free(data);
gprintf("Loading Channel...\n");
entryPoint = entry;
/* Select an appropriate video mode */
GXRModeObj * vmode = __Disc_SelectVMode(vidMode, chantitle);
@ -61,11 +57,6 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
entrypoint appJump = (entrypoint)entryPoint;
if (disableIOSreload)
IOSReloadBlock(IOS_GetVersion(), false);
else
IOSReloadBlock(IOS_GetVersion(), true);
/* Set an appropriate video mode */
__Disc_SetVMode();
@ -79,15 +70,20 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
memset((void *)0x80000000, 0, 6);
*(vu32 *)0x80000000 = TITLE_LOWER(chantitle);
DCFlushRange((void *)0x80000000, 6);
/* Shutdown IOS subsystems */
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
gprintf("Jumping to entrypoint %08x\n", entryPoint);
/* Shutdown IOS subsystems */
u32 level = IRQ_Disable();
__IOS_ShutdownSubsystems();
__exception_closeall();
/* Originally from tueidj - taken from NeoGamma (thx) */
*(vu32*)0xCC003024 = 1;
if (entryPoint != 0x3400)
{
if (hooktype != 0)
if(hooktype != 0)
{
__asm__(
"lis %r3, entryPoint@h\n"
@ -101,9 +97,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
"bctr\n"
);
}
else appJump();
else
appJump();
}
else if (hooktype != 0)
else if(hooktype != 0)
{
__asm__(
"lis %r3, returnpoint@h\n"
@ -126,7 +123,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
"rfi\n"
);
}
else _unstub_start();
else
_unstub_start();
IRQ_Restore(level);
return 0;
}
@ -140,30 +140,30 @@ u32 LoadChannel(u8 *buffer)
dolchunkcount = 0;
dolheader *dolfile = (dolheader *)buffer;
if(dolfile->bss_start)
{
if(!(dolfile->bss_start & 0x80000000))
dolfile->bss_start |= 0x80000000;
if(dolfile->bss_start)
{
if(!(dolfile->bss_start & 0x80000000))
dolfile->bss_start |= 0x80000000;
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
}
int i;
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
}
int i;
for(i = 0; i < 18; i++)
{
if (!dolfile->section_size[i]) continue;
if (dolfile->section_pos[i] < sizeof(dolheader)) continue;
if(!dolfile->section_size[i]) continue;
if(dolfile->section_pos[i] < sizeof(dolheader)) continue;
if(!(dolfile->section_start[i] & 0x80000000)) dolfile->section_start[i] |= 0x80000000;
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
dolchunksize[dolchunkcount] = dolfile->section_size[i];
gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
memmove (dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
dolchunkcount++;
}
@ -216,38 +216,45 @@ bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen)
bool Identify(u64 titleid, u32 *ios)
{
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
gprintf("Reading TMD...");
sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid));
u32 tmdSize;
u8 *tmdBuffer = ISFS_GetFile((u8 *) &filepath, &tmdSize, -1);
if (tmdBuffer == NULL || tmdSize == 0)
{
gprintf("Reading TMD...Failed!\n");
gprintf("Failed!\n");
return false;
}
gprintf("Success!\n");
*ios = (u32)(tmdBuffer[0x18b]);
u32 tikSize;
signed_blob *tikBuffer = NULL;
gprintf("Generating fake ticket...");
if(!Identify_GenerateTik(&tikBuffer,&tikSize))
{
gprintf("Generating fake ticket...Failed!\n");
gprintf("Failed!\n");
return false;
}
gprintf("Success!\n");
gprintf("Reading certs...");
sprintf(filepath, "/sys/cert.sys");
u32 certSize;
u8 *certBuffer = ISFS_GetFile((u8 *) &filepath, &certSize, -1);
if (certBuffer == NULL || certSize == 0)
{
gprintf("Reading certs...Failed!\n");
gprintf("Failed!\n");
MEM2_free(tmdBuffer);
MEM2_free(tikBuffer);
return false;
}
gprintf("Success!\n");
gprintf("ES_Identify\n");
s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL);
if (ret < 0)
{

View File

@ -8,7 +8,7 @@ extern "C" {
#include <gctypes.h>
#include <gccore.h>
s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio);
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio);
u32 LoadChannel(u8 *buffer);
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);

View File

@ -73,15 +73,22 @@ Channels::~Channels()
{
}
u8 * Channels::Load(u64 title)
u32 Channels::Load(u64 title, u32 *ios)
{
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
u32 bootcontent;
u32 entry = 0;
if(!GetAppNameFromTmd(title, app, true, &bootcontent))
return NULL;
return entry;
return GetDol(title, bootcontent);
u8* data = GetDol(title, bootcontent);
Identify(title, ios);
entry = LoadChannel(data);
free(data);
return entry;
}
u8 Channels::GetRequestedIOS(u64 title)
@ -104,11 +111,6 @@ u8 Channels::GetRequestedIOS(u64 title)
return IOS;
}
bool Channels::Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio)
{
return BootChannel(data, chantitle, vidMode, vipatch, countryString, patchVidMode, disableIOSreload, aspectRatio);
}
u64* Channels::GetChannelList(u32* count)
{
u32 countall;

View File

@ -54,10 +54,9 @@ class Channels
void Init(u32 channelType, string lang, bool reload = false);
u8 * Load(u64 title);
u32 Load(u64 title, u32 *ios);
u8 GetRequestedIOS(u64 title);
bool Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio);
int Count();
wchar_t *GetName(int index);
char *GetId(int index);

View File

@ -81,8 +81,14 @@ void Nand::Init(string path, u32 partition, bool disable)
s32 Nand::Nand_Mount(NandDevice *Device)
{
gprintf("Device: %s\n", Device->Name);
s32 fd = IOS_Open("fat", 0);
if (fd < 0) return fd;
if(fd < 0)
{
gprintf("Mount Fail 1\n");
return fd;
}
static ioctlv vector[1] ATTRIBUTE_ALIGN(32);
@ -145,17 +151,28 @@ s32 Nand::Nand_Disable(void)
s32 Nand::Enable_Emu()
{
if(MountedDevice == EmuDevice || Disabled)
{
gprintf("Fail 1\n");
return 0;
}
Disable_Emu();
NandDevice *Device = &NandDeviceList[EmuDevice];
s32 ret = Nand_Mount(Device);
if (ret < 0) return ret;
if(ret < 0)
{
gprintf("Fail 2\n");
return ret;
}
ret = Nand_Enable(Device);
if (ret < 0) return ret;
if(ret < 0)
{
gprintf("Fail 3\n");
return ret;
}
MountedDevice = EmuDevice;

View File

@ -872,8 +872,10 @@ static const char systems[11] = { 'C', 'E', 'F', 'J', 'L', 'M', 'N', 'P', 'Q', '
void CMenu::_launchChannel(dir_discHdr *hdr)
{
Channels channel;
u8 *data = NULL;
u32 ios = 0;
u32 entry = 0;
MEM1_wrap(0);
string id = string((const char *) hdr->hdr.id);
bool forwarder = true;
@ -887,14 +889,10 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
}
forwarder = m_gcfg2.getBool(id, "custom", forwarder) || strncmp(id.c_str(), "WIMC", 4) == 0;
if(!forwarder)
data = channel.Load(hdr->hdr.chantitle);
entry = channel.Load(hdr->hdr.chantitle, &ios);
Nand::Instance()->Disable_Emu();
if(!forwarder && data == NULL) return;
bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false));
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("NAND", "cheat", false));
bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false));
@ -986,7 +984,12 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
gprintf("Return to channel %s. Using new d2x way\n", IOS_Ioctlv(ESHandle, 0xA1, 1, 0, vector) != -101 ? "Succeeded" : "Failed!" );
IOS_Close(ESHandle);
}
if (disableIOSreload)
IOSReloadBlock(IOS_GetVersion(), false);
else
IOSReloadBlock(IOS_GetVersion(), true);
CheckGameSoundThread();
cleanup();
Close_Inputs();
@ -1000,7 +1003,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
if (WII_LaunchTitle(hdr->hdr.chantitle) < 0)
Sys_LoadMenu();
}
else if(!channel.Launch(data, hdr->hdr.chantitle, videoMode, vipatch, countryPatch, patchVidMode, disableIOSreload, aspectRatio))
else if(!BootChannel(entry, hdr->hdr.chantitle, ios, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio))
Sys_LoadMenu();
}