mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-04 18:05:06 +01:00
added USB2 support through Hermes IOS202 (mload)
This commit is contained in:
parent
2917f63aa2
commit
7880c09c4e
@ -18,9 +18,10 @@ include $(DEVKITPPC)/gamecube_rules
|
||||
TARGET := genplus_cube
|
||||
BUILD := build_cube
|
||||
SOURCES := source source/m68k source/z80 source/sound source/ntsc source/cart_hw source/cart_hw/svp \
|
||||
source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds
|
||||
source/gx source/gx/utils source/gx/gui source/gx/fileio source/gx/images source/gx/sounds
|
||||
INCLUDES := source source/m68k source/z80 source/sound source/ntsc source/cart_hw source/cart_hw/svp \
|
||||
build_cube source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds
|
||||
source/gx source/gx/utils source/gx/gui source/gx/fileio source/gx/images source/gx/sounds \
|
||||
$(BUILD)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
|
@ -18,9 +18,10 @@ include $(DEVKITPPC)/wii_rules
|
||||
TARGET := genplus_wii
|
||||
BUILD := build_wii
|
||||
SOURCES := source source/m68k source/z80 source/sound source/ntsc source/cart_hw source/cart_hw/svp \
|
||||
source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds
|
||||
source/gx source/gx/utils source/gx/gui source/gx/fileio source/gx/images source/gx/sounds
|
||||
INCLUDES := source source/m68k source/z80 source/sound source/ntsc source/cart_hw source/cart_hw/svp \
|
||||
build_wii source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds
|
||||
source/gx source/gx/utils source/gx/gui source/gx/fileio source/gx/images source/gx/sounds \
|
||||
$(BUILD)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
@ -80,7 +81,8 @@ endif
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) $(OGGFILES:.ogg=.ogg.o) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||
$(sFILES:.s=.o) $(SFILES:.S=.o)
|
||||
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
||||
$(CURDIR)/source/gx/utils/ehcmodule.elf.o
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of include paths
|
||||
|
@ -127,7 +127,7 @@ static gui_image bg_list[6] =
|
||||
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
||||
{NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
|
||||
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,128}
|
||||
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,64}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -29,6 +29,11 @@
|
||||
#include "aram.h"
|
||||
#include "dvd.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include "usb2storage.h"
|
||||
#include "mload.h"
|
||||
#endif
|
||||
|
||||
#include <fat.h>
|
||||
#include <ogc/cast.h>
|
||||
|
||||
@ -39,14 +44,55 @@
|
||||
u32 Shutdown = 0;
|
||||
|
||||
#ifdef HW_RVL
|
||||
|
||||
/* Power Button callback */
|
||||
/****************************************************************************
|
||||
* Power Button callback
|
||||
***************************************************************************/
|
||||
static void Power_Off(void)
|
||||
{
|
||||
Shutdown = 1;
|
||||
ConfigRequested = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* IOS support
|
||||
***************************************************************************/
|
||||
static bool FindIOS(u32 ios)
|
||||
{
|
||||
s32 ret;
|
||||
u32 n;
|
||||
|
||||
u64 *titles = NULL;
|
||||
u32 num_titles=0;
|
||||
|
||||
ret = ES_GetNumTitles(&num_titles);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
if(num_titles < 1)
|
||||
return false;
|
||||
|
||||
titles = (u64 *)memalign(32, num_titles * sizeof(u64) + 32);
|
||||
if (!titles)
|
||||
return false;
|
||||
|
||||
ret = ES_GetTitles(titles, num_titles);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(titles);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(n=0; n < num_titles; n++)
|
||||
{
|
||||
if((titles[n] & 0xFFFFFFFF)==ios)
|
||||
{
|
||||
free(titles);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
free(titles);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
@ -113,7 +159,8 @@ void reloadrom (int size, char *name)
|
||||
{
|
||||
/* cartridge hot-swap support */
|
||||
uint8 hotswap = 0;
|
||||
if (cart.romsize) hotswap = config.hot_swap;
|
||||
if (cart.romsize)
|
||||
hotswap = config.hot_swap;
|
||||
|
||||
/* Load ROM */
|
||||
cart.romsize = size;
|
||||
@ -157,6 +204,7 @@ void shutdown(void)
|
||||
gx_video_Shutdown();
|
||||
#ifdef HW_RVL
|
||||
DI_Close();
|
||||
mload_close();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -170,14 +218,29 @@ u32 frameticker = 0;
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
/* initialize DVDX */
|
||||
/* try to load IOS 202 */
|
||||
if(IOS_GetVersion() != 202 && FindIOS(202))
|
||||
IOS_ReloadIOS(202);
|
||||
|
||||
if(IOS_GetVersion() == 202)
|
||||
{
|
||||
/* disable DVDX stub */
|
||||
DI_LoadDVDX(false);
|
||||
|
||||
/* load EHCI module & enable USB2 driver */
|
||||
if(mload_init() >= 0 && load_ehci_module())
|
||||
USB2Enable(true);
|
||||
}
|
||||
|
||||
/* initialize DVD driver */
|
||||
DI_Init();
|
||||
#endif
|
||||
|
||||
/* initialize hardware */
|
||||
/* initialize video engine */
|
||||
gx_video_Init();
|
||||
gx_input_Init();
|
||||
|
||||
#ifdef HW_DOL
|
||||
/* initialize DVD driver */
|
||||
DVD_Init ();
|
||||
dvd_drive_detect();
|
||||
#endif
|
||||
@ -185,7 +248,6 @@ int main (int argc, char *argv[])
|
||||
/* initialize FAT devices */
|
||||
if (fatInitDefault())
|
||||
{
|
||||
/* check for default directories */
|
||||
DIR_ITER *dir = NULL;
|
||||
|
||||
/* base directory */
|
||||
@ -195,29 +257,26 @@ int main (int argc, char *argv[])
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
|
||||
/* SRAM & Savestate files directory */
|
||||
/* default SRAM & Savestate files directory */
|
||||
sprintf (pathname, "%s/saves",DEFAULT_PATH);
|
||||
dir = diropen(pathname);
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
|
||||
/* Snapshot files directory */
|
||||
/* default Snapshot files directory */
|
||||
sprintf (pathname, "%s/snaps",DEFAULT_PATH);
|
||||
dir = diropen(pathname);
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
|
||||
/* Cheat files directory */
|
||||
sprintf (pathname, "%s/cheats",DEFAULT_PATH);
|
||||
dir = diropen(pathname);
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
}
|
||||
|
||||
/* initialize sound engine */
|
||||
/* initialize input engine */
|
||||
gx_input_Init();
|
||||
|
||||
/* initialize sound engine (need libfat) */
|
||||
gx_audio_Init();
|
||||
|
||||
/* initialize core engine */
|
||||
/* initialize genesis plus core */
|
||||
legal();
|
||||
config_default();
|
||||
history_default();
|
||||
|
3
source/gx/utils/ehcmodule_elf.h
Normal file
3
source/gx/utils/ehcmodule_elf.h
Normal file
@ -0,0 +1,3 @@
|
||||
extern const u8 ehcmodule_elf_end[];
|
||||
extern const u8 ehcmodule_elf[];
|
||||
extern const u32 ehcmodule_elf_size;
|
281
source/gx/utils/mload.c
Normal file
281
source/gx/utils/mload.c
Normal file
@ -0,0 +1,281 @@
|
||||
/* mload.c (for PPC) (c) 2009, Hermes
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HW_RVL
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#include <ogc/ipc.h>
|
||||
#include "unistd.h"
|
||||
#include "ehcmodule_elf.h"
|
||||
|
||||
#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
|
||||
#define MLOAD_LOAD_MODULE 0x4D4C4480
|
||||
#define MLOAD_RUN_MODULE 0x4D4C4481
|
||||
#define MLOAD_RUN_THREAD 0x4D4C4482
|
||||
|
||||
#define MLOAD_STOP_THREAD 0x4D4C4484
|
||||
#define MLOAD_CONTINUE_THREAD 0x4D4C4485
|
||||
|
||||
#define MLOAD_GET_LOAD_BASE 0x4D4C4490
|
||||
#define MLOAD_MEMSET 0x4D4C4491
|
||||
|
||||
#define MLOAD_GET_EHCI_DATA 0x4D4C44A0
|
||||
|
||||
#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
|
||||
|
||||
#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 ident0;
|
||||
u32 ident1;
|
||||
u32 ident2;
|
||||
u32 ident3;
|
||||
u32 machinetype;
|
||||
u32 version;
|
||||
u32 entry;
|
||||
u32 phoff;
|
||||
u32 shoff;
|
||||
u32 flags;
|
||||
u16 ehsize;
|
||||
u16 phentsize;
|
||||
u16 phnum;
|
||||
u16 shentsize;
|
||||
u16 shnum;
|
||||
u16 shtrndx;
|
||||
} elfheader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 type;
|
||||
u32 offset;
|
||||
u32 vaddr;
|
||||
u32 paddr;
|
||||
u32 filesz;
|
||||
u32 memsz;
|
||||
u32 flags;
|
||||
u32 align;
|
||||
} elfphentry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *start;
|
||||
int prio;
|
||||
void *stack;
|
||||
int size_stack;
|
||||
} data_elf;
|
||||
|
||||
static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload";
|
||||
static s32 mload_fd = -1;
|
||||
|
||||
// to init/test if the device is running
|
||||
int mload_init()
|
||||
{
|
||||
int n;
|
||||
|
||||
if (mload_fd >= 0)
|
||||
return 0;
|
||||
|
||||
for (n = 0; n < 10; n++) // try 2.5 seconds
|
||||
{
|
||||
mload_fd = IOS_Open(mload_fs, 0);
|
||||
|
||||
if (mload_fd >= 0)
|
||||
break;
|
||||
|
||||
usleep(250 * 1000);
|
||||
}
|
||||
|
||||
return mload_fd;
|
||||
}
|
||||
|
||||
// to close the device (remember call it when rebooting the IOS!)
|
||||
int mload_close()
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (mload_fd < 0)
|
||||
return -1;
|
||||
|
||||
ret = IOS_Close(mload_fd);
|
||||
|
||||
mload_fd = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
|
||||
static int mload_seek(int offset, int mode)
|
||||
{
|
||||
if (mload_init() < 0)
|
||||
return -1;
|
||||
return IOS_Seek(mload_fd, offset, mode);
|
||||
}
|
||||
|
||||
// write bytes from starlet (it update the offset)
|
||||
static int mload_write(const void * buf, u32 size)
|
||||
{
|
||||
if (mload_init() < 0)
|
||||
return -1;
|
||||
return IOS_Write(mload_fd, buf, size);
|
||||
}
|
||||
|
||||
// fill a block (similar to memset)
|
||||
static int mload_memset(void *starlet_addr, int set, int len)
|
||||
{
|
||||
int ret;
|
||||
s32 hid = -1;
|
||||
|
||||
if (mload_init() < 0)
|
||||
return -1;
|
||||
|
||||
hid = iosCreateHeap(0x800);
|
||||
|
||||
if (hid < 0)
|
||||
return hid;
|
||||
|
||||
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr,
|
||||
set, len);
|
||||
|
||||
iosDestroyHeap(hid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// load a module from the PPC
|
||||
// the module must be a elf made with stripios
|
||||
static int mload_elf(void *my_elf, data_elf *data_elf)
|
||||
{
|
||||
int n, m;
|
||||
int p;
|
||||
u8 *adr;
|
||||
u32 elf = (u32) my_elf;
|
||||
|
||||
if (elf & 3)
|
||||
return -1; // aligned to 4 please!
|
||||
|
||||
elfheader *head = (void *) elf;
|
||||
elfphentry *entries;
|
||||
|
||||
if (head->ident0 != 0x7F454C46)
|
||||
return -1;
|
||||
if (head->ident1 != 0x01020161)
|
||||
return -1;
|
||||
if (head->ident2 != 0x01000000)
|
||||
return -1;
|
||||
|
||||
p = head->phoff;
|
||||
|
||||
data_elf->start = (void *) head->entry;
|
||||
|
||||
for (n = 0; n < head->phnum; n++)
|
||||
{
|
||||
entries = (void *) (elf + p);
|
||||
p += sizeof(elfphentry);
|
||||
|
||||
if (entries->type == 4)
|
||||
{
|
||||
adr = (void *) (elf + entries->offset);
|
||||
|
||||
if (getbe32(0) != 0)
|
||||
return -2; // bad info (sure)
|
||||
|
||||
for (m = 4; m < entries->memsz; m += 8)
|
||||
{
|
||||
switch (getbe32(m))
|
||||
{
|
||||
case 0x9:
|
||||
data_elf->start = (void *) getbe32(m+4);
|
||||
break;
|
||||
case 0x7D:
|
||||
data_elf->prio = getbe32(m+4);
|
||||
break;
|
||||
case 0x7E:
|
||||
data_elf->size_stack = getbe32(m+4);
|
||||
break;
|
||||
case 0x7F:
|
||||
data_elf->stack = (void *) (getbe32(m+4));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (entries->type == 1 && entries->memsz != 0 && entries->vaddr != 0)
|
||||
{
|
||||
|
||||
if (mload_memset((void *) entries->vaddr, 0, entries->memsz) < 0)
|
||||
return -1;
|
||||
if (mload_seek(entries->vaddr, SEEK_SET) < 0)
|
||||
return -1;
|
||||
if (mload_write((void *) (elf + entries->offset), entries->filesz) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// run one thread (you can use to load modules or binary files)
|
||||
static int mload_run_thread(void *starlet_addr, void *starlet_top_stack,
|
||||
int stack_size, int priority)
|
||||
{
|
||||
int ret;
|
||||
s32 hid = -1;
|
||||
|
||||
if (mload_init() < 0)
|
||||
return -1;
|
||||
|
||||
hid = iosCreateHeap(0x800);
|
||||
|
||||
if (hid < 0)
|
||||
return hid;
|
||||
|
||||
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:",
|
||||
starlet_addr, starlet_top_stack, stack_size, priority);
|
||||
|
||||
iosDestroyHeap(hid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool load_ehci_module()
|
||||
{
|
||||
data_elf my_data_elf;
|
||||
my_data_elf.start = NULL;
|
||||
my_data_elf.prio = 0;
|
||||
my_data_elf.stack = NULL;
|
||||
my_data_elf.size_stack = 0;
|
||||
|
||||
if(mload_elf((void *) ehcmodule_elf, &my_data_elf) != 0)
|
||||
return false;
|
||||
|
||||
if (mload_run_thread(my_data_elf.start, my_data_elf.stack,
|
||||
my_data_elf.size_stack, my_data_elf.prio) < 0)
|
||||
{
|
||||
usleep(1000);
|
||||
if (mload_run_thread(my_data_elf.start, my_data_elf.stack,
|
||||
my_data_elf.size_stack, 0x47) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
33
source/gx/utils/mload.h
Normal file
33
source/gx/utils/mload.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* mload.c (for PPC) (c) 2009, Hermes
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __MLOAD_H__
|
||||
#define __MLOAD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int mload_init();
|
||||
bool load_ehci_module();
|
||||
int mload_close();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
455
source/gx/utils/usb2storage.c
Normal file
455
source/gx/utils/usb2storage.c
Normal file
@ -0,0 +1,455 @@
|
||||
/*-------------------------------------------------------------
|
||||
|
||||
usb2storage.c -- USB mass storage support, inside starlet
|
||||
Copyright (C) 2008 Kwiirk
|
||||
Improved for homebrew by rodries
|
||||
|
||||
If this driver is linked before libogc, this will replace the original
|
||||
usbstorage driver by svpe from libogc
|
||||
|
||||
CIOS_usb2 must be loaded!
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
#ifdef HW_RVL
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
#include <ogc/lwp_heap.h>
|
||||
#include <malloc.h>
|
||||
#include <ogc/disc_io.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
#include <ogc/mutex.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ogc/machine/processor.h>
|
||||
#include <ogc/ipc.h>
|
||||
|
||||
//#define DEBUG_USB2
|
||||
|
||||
#ifdef DEBUG_USB2
|
||||
#define debug_printf(fmt, args...) \
|
||||
fprintf(stderr, "%s:%d:" fmt, __FUNCTION__, __LINE__, ##args)
|
||||
#else
|
||||
#define debug_printf(fmt, args...)
|
||||
#endif // DEBUG_USB2
|
||||
|
||||
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
|
||||
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
|
||||
#define USB_IOCTL_UMS_IS_INSERTED (UMS_BASE+0x7)
|
||||
|
||||
#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10)
|
||||
#define USB_IOCTL_UMS_START (UMS_BASE+0x11)
|
||||
#define USB_IOCTL_UMS_STOP (UMS_BASE+0x12)
|
||||
#define USB_IOCTL_UMS_EXIT (UMS_BASE+0x16)
|
||||
|
||||
#define UMS_HEAPSIZE 2*1024
|
||||
#define UMS_MAXPATH 16
|
||||
|
||||
static s32 hId = -1;
|
||||
static s32 fd = -1;
|
||||
static u32 sector_size;
|
||||
static s32 usb2 = -1;
|
||||
static mutex_t usb2_mutex = LWP_MUTEX_NULL;
|
||||
static u8 *fixed_buffer = NULL;
|
||||
static s32 usb2_inited = 0;
|
||||
|
||||
#define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f)
|
||||
#define USB2_BUFFER 128*1024
|
||||
static heap_cntrl usb2_heap;
|
||||
static u8 __usb2_heap_created = 0;
|
||||
|
||||
static DISC_INTERFACE __io_usb1storage;
|
||||
static int usb1disc_inited = 0;
|
||||
extern const DISC_INTERFACE __io_usb2storage;
|
||||
static int currentMode = 2; // 1 = use USB1 interface, 2 = use USB2 interface
|
||||
|
||||
static s32 USB2CreateHeap()
|
||||
{
|
||||
u32 level;
|
||||
void *usb2_heap_ptr;
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
|
||||
if (__usb2_heap_created != 0)
|
||||
{
|
||||
_CPU_ISR_Restore(level);
|
||||
return IPC_OK;
|
||||
}
|
||||
|
||||
usb2_heap_ptr = (void *) ROUNDDOWN32(((u32)SYS_GetArena2Hi() - (USB2_BUFFER+(4*1024))));
|
||||
if ((u32) usb2_heap_ptr < (u32) SYS_GetArena2Lo())
|
||||
{
|
||||
_CPU_ISR_Restore(level);
|
||||
return IPC_ENOMEM;
|
||||
}
|
||||
SYS_SetArena2Hi(usb2_heap_ptr);
|
||||
__lwp_heap_init(&usb2_heap, usb2_heap_ptr, (USB2_BUFFER + (4 * 1024)), 32);
|
||||
__usb2_heap_created = 1;
|
||||
_CPU_ISR_Restore(level);
|
||||
return IPC_OK;
|
||||
}
|
||||
|
||||
static s32 USB2Storage_Initialize(int verbose)
|
||||
{
|
||||
s32 ret = USB_OK;
|
||||
u32 size = 0;
|
||||
char *devicepath = NULL;
|
||||
|
||||
//if(usb2_inited) return ret;
|
||||
|
||||
if (usb2_mutex == LWP_MUTEX_NULL)
|
||||
LWP_MutexInit(&usb2_mutex, false);
|
||||
|
||||
LWP_MutexLock(usb2_mutex);
|
||||
|
||||
if (hId == -1)
|
||||
hId = iosCreateHeap(UMS_HEAPSIZE);
|
||||
|
||||
if (hId < 0)
|
||||
{
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
debug_printf("error IPC_ENOMEM\n",fd);
|
||||
return IPC_ENOMEM;
|
||||
}
|
||||
|
||||
if (USB2CreateHeap() != IPC_OK)
|
||||
{
|
||||
debug_printf("error USB2 IPC_ENOMEM\n",fd);
|
||||
return IPC_ENOMEM;
|
||||
}
|
||||
|
||||
if (fixed_buffer == NULL)
|
||||
fixed_buffer = __lwp_heap_allocate(&usb2_heap, USB2_BUFFER);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
devicepath = iosAlloc(hId, UMS_MAXPATH);
|
||||
if (devicepath == NULL)
|
||||
{
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
return IPC_ENOMEM;
|
||||
}
|
||||
|
||||
snprintf(devicepath, USB_MAXPATH, "/dev/usb2");
|
||||
fd = IOS_Open(devicepath, 0);
|
||||
iosFree(hId, devicepath);
|
||||
}
|
||||
|
||||
ret = fd;
|
||||
debug_printf("usb2 fd: %d\n",fd);
|
||||
usleep(500);
|
||||
|
||||
if (fd > 0)
|
||||
{
|
||||
if (verbose)
|
||||
ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_SET_VERBOSE, ":");
|
||||
ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_INIT, ":");
|
||||
debug_printf("usb2 init value: %i\n", ret);
|
||||
|
||||
if (ret < 0)
|
||||
debug_printf("usb2 error init\n");
|
||||
else
|
||||
size = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i",
|
||||
§or_size);
|
||||
debug_printf("usb2 GET_CAPACITY: %d\n", size);
|
||||
|
||||
if (size == 0)
|
||||
ret = -2012;
|
||||
else
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
|
||||
if(ret >= 0)
|
||||
usb2_inited = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int is_MEM2_buffer(const void *buffer)
|
||||
{
|
||||
u32 high_addr = ((u32) buffer) >> 24;
|
||||
return (high_addr == 0x90) || (high_addr == 0xD0);
|
||||
}
|
||||
|
||||
void USB2Enable(bool enable)
|
||||
{
|
||||
if(!usb1disc_inited)
|
||||
{
|
||||
usb1disc_inited = 1;
|
||||
memcpy(&__io_usb1storage, &__io_usbstorage, sizeof(DISC_INTERFACE));
|
||||
}
|
||||
|
||||
if(!enable)
|
||||
{
|
||||
__io_usbstorage = __io_usb1storage;
|
||||
}
|
||||
else
|
||||
{
|
||||
//USB2Storage_Initialize(0);
|
||||
__io_usbstorage = __io_usb2storage;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static s32 USB2Storage_Get_Capacity(u32*_sector_size)
|
||||
{
|
||||
if(fd>0)
|
||||
{
|
||||
LWP_MutexLock(usb2_mutex);
|
||||
s32 ret = IOS_IoctlvFormat(hId,fd,USB_IOCTL_UMS_GET_CAPACITY,":i",§or_size);
|
||||
if(_sector_size)
|
||||
*_sector_size = sector_size;
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return IPC_ENOENT;
|
||||
}
|
||||
|
||||
s32 GetInitValue()
|
||||
{
|
||||
return usb2_init_value;
|
||||
}
|
||||
|
||||
s32 USB2Unmount()
|
||||
{
|
||||
return IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_UMOUNT, ":");
|
||||
}
|
||||
s32 USB2Start()
|
||||
{
|
||||
return IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_START, ":");
|
||||
}
|
||||
s32 USB2Stop()
|
||||
{
|
||||
return IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_STOP, ":");
|
||||
}
|
||||
|
||||
void USB2Close()
|
||||
{
|
||||
if (fd > 0)
|
||||
IOS_Close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
int USB2ReadSector(u32 sector)
|
||||
{
|
||||
void *b;
|
||||
s32 ret;
|
||||
b = malloc(1024);
|
||||
ret = USBStorage_Read_Sectors(sector, 1, b);
|
||||
free(b);
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
static bool __usb2storage_Startup(void)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
usb2 = USB2Storage_Initialize(0);
|
||||
|
||||
if(usb2 >= 0)
|
||||
{
|
||||
currentMode = 2;
|
||||
ret = true;
|
||||
}
|
||||
else if (usb2 < 0)
|
||||
{
|
||||
ret = __io_usb1storage.startup();
|
||||
|
||||
if(ret)
|
||||
currentMode = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool __usb2storage_IsInserted(void)
|
||||
{
|
||||
int retval;
|
||||
bool ret = false;
|
||||
|
||||
if (usb2 == -1)
|
||||
{
|
||||
retval = __usb2storage_Startup();
|
||||
debug_printf("__usb2storage_Startup ret: %d fd: %i\n",retval,fd);
|
||||
}
|
||||
//else
|
||||
LWP_MutexLock(usb2_mutex);
|
||||
if (fd > 0)
|
||||
{
|
||||
|
||||
retval = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_IS_INSERTED, ":");
|
||||
debug_printf("isinserted usb2 retval: %d ret: %d\n",retval,ret);
|
||||
|
||||
if (retval > 0)
|
||||
{
|
||||
currentMode = 2;
|
||||
ret = true;
|
||||
debug_printf("isinserted(2) usb2 retval: %d ret: %d\n",retval,ret);
|
||||
}
|
||||
|
||||
}
|
||||
if(ret==false)
|
||||
{
|
||||
retval = __io_usb1storage.isInserted();
|
||||
|
||||
if (retval > 0)
|
||||
{
|
||||
debug_printf("isinserted usb1 retval: %d\n",retval);
|
||||
currentMode = 1;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
debug_printf("final isinserted usb2 retval: %d ret: %d\n",retval,ret);
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer)
|
||||
{
|
||||
s32 ret = 1;
|
||||
u32 sectors = 0;
|
||||
uint8_t *dest = buffer;
|
||||
|
||||
if (currentMode == 1)
|
||||
return __io_usb1storage.readSectors(sector, numSectors, buffer);
|
||||
|
||||
if (fd < 1)
|
||||
return IPC_ENOENT;
|
||||
|
||||
LWP_MutexLock(usb2_mutex);
|
||||
|
||||
while (numSectors > 0)
|
||||
{
|
||||
if (numSectors * sector_size > USB2_BUFFER)
|
||||
sectors = USB2_BUFFER / sector_size;
|
||||
else
|
||||
sectors = numSectors;
|
||||
|
||||
if (!is_MEM2_buffer(dest)) //libfat is not providing us good buffers :-(
|
||||
{
|
||||
ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d",
|
||||
sector, sectors, fixed_buffer, sector_size * sectors);
|
||||
memcpy(dest, fixed_buffer, sector_size * sectors);
|
||||
}
|
||||
else
|
||||
ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d",
|
||||
sector, sectors, dest, sector_size * sectors);
|
||||
|
||||
dest += sector_size * sectors;
|
||||
if (ret < 1) break;
|
||||
|
||||
sector += sectors;
|
||||
numSectors -= sectors;
|
||||
}
|
||||
if(ret<1)usb2 = -1;
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
if (ret < 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __usb2storage_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
|
||||
{
|
||||
s32 ret = 1;
|
||||
u32 sectors = 0;
|
||||
uint8_t *dest = (uint8_t *) buffer;
|
||||
|
||||
if (currentMode == 1)
|
||||
return __io_usb1storage.writeSectors(sector, numSectors, buffer);
|
||||
|
||||
if (fd < 1)
|
||||
return IPC_ENOENT;
|
||||
|
||||
LWP_MutexLock(usb2_mutex);
|
||||
while (numSectors > 0 && ret > 0)
|
||||
{
|
||||
if (numSectors * sector_size > USB2_BUFFER)
|
||||
sectors = USB2_BUFFER / sector_size;
|
||||
else
|
||||
sectors = numSectors;
|
||||
|
||||
numSectors -= sectors;
|
||||
|
||||
if (!is_MEM2_buffer(dest)) // libfat is not providing us good buffers :-(
|
||||
{
|
||||
memcpy(fixed_buffer, dest, sector_size * sectors);
|
||||
ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_WRITE_SECTORS,
|
||||
"ii:d", sector, sectors, fixed_buffer, sector_size
|
||||
* sectors);
|
||||
}
|
||||
else
|
||||
ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_WRITE_SECTORS,
|
||||
"ii:d", sector, sectors, dest, sector_size * sectors);
|
||||
if (ret < 1)break;
|
||||
|
||||
dest += sector_size * sectors;
|
||||
sector += sectors;
|
||||
}
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
if(ret < 1 ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __usb2storage_ClearStatus(void)
|
||||
{
|
||||
if (currentMode == 1)
|
||||
return __io_usb1storage.clearStatus();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __usb2storage_Shutdown(void)
|
||||
{
|
||||
if (currentMode == 1)
|
||||
return __io_usb1storage.shutdown();
|
||||
|
||||
LWP_MutexLock(usb2_mutex);
|
||||
debug_printf("__usb2storage_Shutdown\n");
|
||||
usb2 = -1;
|
||||
LWP_MutexUnlock(usb2_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
const DISC_INTERFACE __io_usb2storage = {
|
||||
DEVICE_TYPE_WII_USB,
|
||||
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
|
||||
(FN_MEDIUM_STARTUP) & __usb2storage_Startup,
|
||||
(FN_MEDIUM_ISINSERTED) & __usb2storage_IsInserted,
|
||||
(FN_MEDIUM_READSECTORS) & __usb2storage_ReadSectors,
|
||||
(FN_MEDIUM_WRITESECTORS) & __usb2storage_WriteSectors,
|
||||
(FN_MEDIUM_CLEARSTATUS) & __usb2storage_ClearStatus,
|
||||
(FN_MEDIUM_SHUTDOWN) & __usb2storage_Shutdown
|
||||
};
|
||||
#endif
|
16
source/gx/utils/usb2storage.h
Normal file
16
source/gx/utils/usb2storage.h
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
#ifndef __USB2STORAGE_H__
|
||||
#define __USB2STORAGE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void USB2Enable(bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -21,7 +21,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
***************************************************************************/
|
||||
#if defined(HW_RVL)
|
||||
#ifdef HW_RVL
|
||||
|
||||
#include <string.h>
|
||||
#include <gccore.h>
|
@ -21,7 +21,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
***************************************************************************/
|
||||
#if defined(HW_RVL)
|
||||
#ifdef HW_RVL
|
||||
|
||||
typedef enum
|
||||
{
|
@ -2028,7 +2028,7 @@ unsigned int YM2612Read(void)
|
||||
}
|
||||
|
||||
/* Generate 16 bits samples for ym2612 */
|
||||
void YM2612Update(INT32 *buffer, int length)
|
||||
void YM2612Update(long int *buffer, int length)
|
||||
{
|
||||
int i;
|
||||
long int lt,rt;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
extern int YM2612Init(float clock, int rate);
|
||||
extern int YM2612ResetChip(void);
|
||||
extern void YM2612Update(INT32 *buffer, int length);
|
||||
extern void YM2612Update(long int *buffer, int length);
|
||||
extern void YM2612Write(unsigned int a, unsigned int v);
|
||||
extern unsigned int YM2612Read(void);
|
||||
extern unsigned char *YM2612GetContextPtr(void);
|
||||
|
Loading…
Reference in New Issue
Block a user