diff --git a/channel/channelapp/config.h b/channel/channelapp/config.h index e47b7e0..9a80008 100644 --- a/channel/channelapp/config.h +++ b/channel/channelapp/config.h @@ -1,8 +1,8 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#define CHANNEL_VERSION_DATE 201611230000llu -#define CHANNEL_VERSION_STR "1.1.3" +#define CHANNEL_VERSION_DATE 201710120000llu +#define CHANNEL_VERSION_STR "1.1.4" //#define DEBUG_APP //#define DEBUG_STUB diff --git a/channel/channelapp/source/controls.c b/channel/channelapp/source/controls.c index 3e7c890..c2fa7fe 100644 --- a/channel/channelapp/source/controls.c +++ b/channel/channelapp/source/controls.c @@ -20,8 +20,8 @@ static int rumbling = 0; void controls_init (void) { WiiDRC_Init (); if(WiiDRC_Inited() && WiiDRC_Connected()) - { //Wii VC cannot go back to this channel - memset((u32 *) 0x80001800, 0, 0x1800); + { //Set stub to do Wii VC routine + *(vu32*)0x8000180C = 1; DCFlushRange((u32 *) 0x80001800, 0x1800); } diff --git a/channel/channelapp/stub/di.c b/channel/channelapp/stub/di.c new file mode 100644 index 0000000..1b1b29d --- /dev/null +++ b/channel/channelapp/stub/di.c @@ -0,0 +1,118 @@ +/* + TinyLoad - a simple region free (original) game launcher in 4k + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +// Copyright 2008-2009 Hector Martin + +#include "stub_debug.h" +#include "ios.h" +#include "processor.h" +#include "di.h" + +int di_fd=0; + +u32 inbuf[16] ATTRIBUTE_ALIGN(64); +u32 outbuf[16] ATTRIBUTE_ALIGN(64); + +extern u32 __bss_start[]; +extern u32 __bss_end[]; + +int di_init(void) +{ + debug_string("Opening /dev/di: "); + di_fd = ios_open("/dev/di",0); + debug_uint(di_fd); + debug_string("\n"); + //memset(inbuf, 0, 0x20 ); + return di_fd; +} + +int di_shutdown(void) +{ + return ios_close(di_fd); +} + +static int _di_ioctl_std(int num) __attribute__((noinline)); +static int _di_ioctl_std(int num) +{ + inbuf[0x00] = num << 24; + return ios_ioctl( di_fd, num, inbuf, 0x20, outbuf, 0x20); +} + +int di_identify(void) +{ + //memset(inbuf, 0, 0x20 ); + //memset(outbuf, 0, 0x20 ); + + //inbuf[0x00] = 0x12000000; + + return _di_ioctl_std(0x12); +} + +int di_read(void *dst, u32 size, u32 offset) +{ + //memset(inbuf, 0, 0x20 ); + + inbuf[0x00] = 0x71000000; + inbuf[0x01] = size; + inbuf[0x02] = offset; + + return ios_ioctl( di_fd, 0x71, inbuf, 0x20, dst, size); +} + +int di_unencryptedread(void *dst, u32 size, u32 offset) +{ + //memset(inbuf, 0, 0x20 ); + + inbuf[0x00] = 0x8D000000; + inbuf[0x01] = size; + inbuf[0x02] = offset; + + return ios_ioctl( di_fd, 0x8D, inbuf, 0x20, dst, size); +} + +int di_reset(void) +{ + //memset(inbuf, 0, 0x20 ); + + //inbuf[0x00] = 0x8A000000; + inbuf[0x01] = 1; + + return _di_ioctl_std(0x8A); +} + +int di_openpartition(u32 offset, u8 *tmd) +{ + static struct ioctlv vectors[16] ATTRIBUTE_ALIGN(64); + + //memset(inbuf, 0, 0x20 ); + inbuf[0x00] = 0x8B000000; + inbuf[0x01] = offset; + + vectors[0].data = inbuf; + vectors[0].len = 0x20; + vectors[1].data = NULL; + vectors[1].len = 0x2a4; + vectors[2].data = NULL; + vectors[2].len = 0; + + vectors[3].data = tmd; + vectors[3].len = 0x49e4; + vectors[4].data = outbuf; + vectors[4].len = 0x20; + + return ios_ioctlv(di_fd, 0x8B, 3, 2, vectors); +} + +int di_readdiscid(void *dst) +{ + //memset(inbuf, 0, 0x20 ); + //memset(dst, 0, 0x20 ); + + inbuf[0x00] = 0x70000000; + + return ios_ioctl( di_fd, 0x70, inbuf, 0x20, dst, 0x20); +} diff --git a/channel/channelapp/stub/di.h b/channel/channelapp/stub/di.h new file mode 100644 index 0000000..7c6ae8b --- /dev/null +++ b/channel/channelapp/stub/di.h @@ -0,0 +1,25 @@ +/* + TinyLoad - a simple region free (original) game launcher in 4k + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +// Copyright 2008-2009 Hector Martin + +#ifndef __DI_H__ +#define __DI_H__ + +int di_init(void); +int di_getcoverstatus(void); +int di_requesterror(void); +int di_read(void *dst, u32 size, u32 offset); +int di_unencryptedread(void *dst, u32 size, u32 offset); +int di_identify(void); +int di_reset(void); +int di_stopmotor(void); +int di_openpartition(u32 offset, u8 *tmd); +int di_closepartition(void); +int di_readdiscid(void *dst); +int di_shutdown(void); +#endif \ No newline at end of file diff --git a/channel/channelapp/stub/ios.c b/channel/channelapp/stub/ios.c index 7cfe290..f94b119 100644 --- a/channel/channelapp/stub/ios.c +++ b/channel/channelapp/stub/ios.c @@ -205,6 +205,33 @@ int ios_close(int fd) return ipc.result; } +int ios_ioctl(int fd, u32 n, void *in, u32 in_size, void *out, u32 out_size) +{ + memset(&ipc, 0, sizeof ipc); + + if(in) + DCFlushRange(in, in_size); + if(out) + DCFlushRange(out, out_size); + + ipc.arg[0] = n; + ipc.arg[1] = (u32)virt_to_phys(in); + ipc.arg[2] = in_size; + ipc.arg[3] = (u32)virt_to_phys(out); + ipc.arg[4] = out_size; + + ipc.cmd = 6; + ipc.fd = fd; + + ipc_send_request(); + ipc_recv_reply(); + + if(out) + DCInvalidateRange(out, out_size); + + return ipc.result; +} + int _ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec, int reboot) { u32 i; diff --git a/channel/channelapp/stub/ios.h b/channel/channelapp/stub/ios.h index e53fcb4..f64b8ae 100644 --- a/channel/channelapp/stub/ios.h +++ b/channel/channelapp/stub/ios.h @@ -6,6 +6,7 @@ struct ioctlv { int ios_open(const char *filename, u32 mode); int ios_close(int fd); +int ios_ioctl(int fd, u32 n, void *in, u32 in_size, void *out, u32 out_size); int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec); int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec); void reset_ios(void); diff --git a/channel/channelapp/stub/stub.c b/channel/channelapp/stub/stub.c index db9978d..7bd0570 100644 --- a/channel/channelapp/stub/stub.c +++ b/channel/channelapp/stub/stub.c @@ -24,13 +24,38 @@ #include "usb.h" #include "ios.h" #include "cache.h" +#include "di.h" #include "../config.h" #define IOCTL_ES_LAUNCH 0x08 #define IOCTL_ES_GETVIEWCNT 0x12 #define IOCTL_ES_GETVIEWS 0x13 -struct ioctlv vecs[3] __attribute__((aligned(32))); +static struct ioctlv vecs[3] __attribute__((aligned(32))); + +static u32 disc_id[0x40] __attribute__((aligned(32))); + +static u8 tmd[0x5000] __attribute__((aligned(64))); + +static struct { + u32 count; + u32 offset; + u32 pad[6]; +} part_table_info __attribute__((aligned(32))); + +static struct { + u32 offset; + u32 type; +} partition_table[32] __attribute__((aligned(32))); + +static struct +{ + char revision[16]; + void *entry; + s32 size; + s32 trailersize; + s32 padding; +} apploader_hdr __attribute__((aligned(32))); u64 *conf_magic = STUB_ADDR_MAGIC; u64 *conf_titleID = STUB_ADDR_TITLE; @@ -115,6 +140,7 @@ int es_init(void) { return es_fd; } +static void no_report(const char *fmt __attribute__((unused)), ...) { } void _main (void) { int iosver; @@ -125,25 +151,74 @@ void _main (void) { if(*conf_magic == STUB_MAGIC) titleID = *conf_titleID; reset_ios(); + if(*(vu32*)0x8000180C == 1) //if Wii VC + { + //Code from TinyLoad - a simple region free (original) game launcher in 4k + void (*app_entry)(void(**init)(void (*report)(const char *fmt, ...)), int (**main)(), void *(**final)()); + void (*app_init)(void (*report)(const char *fmt, ...)); + int (*app_main)(void **dst, int *size, int *offset); + void *(*app_final)(void); + void (*entrypoint)(void) __attribute__((noreturn)); - if(es_init() < 0) goto fail; + di_init(); + di_reset(); + di_identify(); + di_readdiscid(disc_id); + di_unencryptedread(&part_table_info, sizeof(part_table_info), 0x10000); + di_unencryptedread(partition_table, sizeof(partition_table), part_table_info.offset); + int i; + for(i=0; i