mirror of
https://github.com/project-slippi/Nintendont.git
synced 2025-10-06 00:22:40 +02:00
To prevent endless revision/version confusion nintendont will no longer use revisions but versions starting at 1.0
1.0: release = r89 date = 2014-4-27 -If your loader provides a return stub, the reset combination will now use it, if no loader was used, you will return to the system menu release = r88 date = 2014-4-26 -Added Mayflash 3 in 1 Magic Joy Box support (Thanks Adeka & Fludit) -Added Thrustmaster Firestorm Dual Analog 2 support -Cleared message to plug in HID controller once it is plugged in -Added error message for "PS3 controller init error" -Added display of error codes for unknown HID init errors -Added updates.txt release = r87 date = 2014-4-26 -Removed the DSP patches release = r86 date = 2014-4-26 -Added a dead zone to L and R triggers for both GameCube and USB controllers, should stop triggers from staying at one place release = r85 date = 2014-4-25 -Moved r85 to new SVN
This commit is contained in:
37
Build.bat
Normal file
37
Build.bat
Normal file
@@ -0,0 +1,37 @@
|
||||
@echo off
|
||||
|
||||
cd resetstub
|
||||
echo.
|
||||
echo Building Reset Stub
|
||||
echo.
|
||||
make clean
|
||||
make
|
||||
|
||||
cd ..\kernel
|
||||
echo.
|
||||
echo Building Nintendont Kernel (USB)
|
||||
echo.
|
||||
make usb=1 clean
|
||||
make usb=1
|
||||
|
||||
echo.
|
||||
echo Building Nintendont Kernel (SD)
|
||||
echo.
|
||||
make clean
|
||||
make
|
||||
|
||||
cd ..\loader\source\ppc
|
||||
echo.
|
||||
echo Building Nintendont HID
|
||||
echo.
|
||||
call build.bat
|
||||
|
||||
cd ..\..\..\loader
|
||||
echo.
|
||||
echo Building Nintendont Loader
|
||||
echo.
|
||||
make clean
|
||||
make
|
||||
|
||||
echo.
|
||||
pause
|
84
common/include/CommonConfig.h
Normal file
84
common/include/CommonConfig.h
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
#ifndef __COMMON_CONFIG_H__
|
||||
#define __COMMON_CONFIG_H__
|
||||
|
||||
#include "NintendontVersion.h"
|
||||
#include "Metadata.h"
|
||||
|
||||
#define NIN_CFG_VERSION 0x00000002
|
||||
|
||||
#define NIN_CFG_MAXPAD 4
|
||||
|
||||
typedef struct NIN_CFG
|
||||
{
|
||||
unsigned int Magicbytes; // 0x01070CF6
|
||||
unsigned int Version; // 0x00000001
|
||||
unsigned int Config;
|
||||
unsigned int VideoMode;
|
||||
unsigned int Language;
|
||||
char GamePath[255];
|
||||
char CheatPath[255];
|
||||
unsigned int MaxPads;
|
||||
unsigned int GameID;
|
||||
} NIN_CFG;
|
||||
|
||||
enum ninconfig
|
||||
{
|
||||
NIN_CFG_CHEATS = (1<<0),
|
||||
NIN_CFG_DEBUGGER = (1<<1), // Only for Wii Version
|
||||
NIN_CFG_DEBUGWAIT = (1<<2), // Only for Wii Version
|
||||
NIN_CFG_MEMCARDEMU = (1<<3),
|
||||
NIN_CFG_CHEAT_PATH = (1<<4),
|
||||
NIN_CFG_FORCE_WIDE = (1<<5),
|
||||
NIN_CFG_FORCE_PROG = (1<<6),
|
||||
NIN_CFG_AUTO_BOOT = (1<<7),
|
||||
NIN_CFG_HID = (1<<8),
|
||||
NIN_CFG_OSREPORT = (1<<9),
|
||||
NIN_CFG_USB = (1<<10),
|
||||
};
|
||||
|
||||
enum ninvideomode
|
||||
{
|
||||
NIN_VID_AUTO = (0<<16),
|
||||
NIN_VID_FORCE = (1<<16),
|
||||
NIN_VID_NONE = (2<<16),
|
||||
|
||||
NIN_VID_MASK = NIN_VID_AUTO|NIN_VID_FORCE|NIN_VID_NONE,
|
||||
|
||||
NIN_VID_FORCE_PAL50 = (1<<0),
|
||||
NIN_VID_FORCE_PAL60 = (1<<1),
|
||||
NIN_VID_FORCE_NTSC = (1<<2),
|
||||
NIN_VID_FORCE_MPAL = (1<<3),
|
||||
|
||||
NIN_VID_FORCE_MASK = NIN_VID_FORCE_PAL50|NIN_VID_FORCE_PAL60|NIN_VID_FORCE_NTSC|NIN_VID_FORCE_MPAL,
|
||||
|
||||
NIN_VID_PROG = (1<<4), //important to prevent blackscreens
|
||||
};
|
||||
|
||||
enum ninlanguage
|
||||
{
|
||||
NIN_LAN_ENGLISH = 0,
|
||||
NIN_LAN_GERMAN = 1,
|
||||
NIN_LAN_FRENCH = 2,
|
||||
NIN_LAN_SPANISH = 3,
|
||||
NIN_LAN_ITALIAN = 4,
|
||||
NIN_LAN_DUTCH = 5,
|
||||
|
||||
/* Auto will use English for E/P region codes and
|
||||
only other languages when these region codes are used: D/F/S/I/J */
|
||||
|
||||
NIN_LAN_AUTO = -1,
|
||||
};
|
||||
|
||||
enum VideoModes
|
||||
{
|
||||
GCVideoModeNone = 0,
|
||||
GCVideoModePAL60 = 1,
|
||||
GCVideoModeNTSC = 2,
|
||||
GCVideoModePROG = 3,
|
||||
};
|
||||
|
||||
#define NIN_RAW_MEMCARD_SIZE 2*1024*1024 //2MB
|
||||
#define NIN_MEMCARD_BLOCKS 0x00000010 //251 Blocks
|
||||
|
||||
#endif
|
14
common/include/Metadata.h
Normal file
14
common/include/Metadata.h
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
#ifndef __META_DATA_H__
|
||||
#define __META_DATA_H__
|
||||
|
||||
#define META_NAME "Nintendont"
|
||||
#define META_AUTHOR "crediar"
|
||||
|
||||
#define META_LONG1 "Commiters: JoostinOnline, Greyrogue, Howard, Cyan \r\n\r\n Project website: https://nintendont.googlecode.com/ "
|
||||
#define META_LONG2 "Nintendont allows you to run GameCube games on a Wii or Wii U from an SD or HDD device."
|
||||
#define META_SHORT "Gamecube Loader"
|
||||
|
||||
#define META_XML "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"yes\"?>"
|
||||
|
||||
#endif
|
10
common/include/NintendontVersion.h
Normal file
10
common/include/NintendontVersion.h
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#ifndef __NINTENDONT_VERSION_H__
|
||||
#define __NINTENDONT_VERSION_H__
|
||||
|
||||
#define NIN_MAJOR_VERSION 1
|
||||
#define NIN_MINOR_VERSION 0
|
||||
|
||||
#define NIN_VERSION ((NIN_MAJOR_VERSION << 16) | NIN_MINOR_VERSION)
|
||||
|
||||
#endif
|
BIN
controllerconfigs/HID_Test.dol
Normal file
BIN
controllerconfigs/HID_Test.dol
Normal file
Binary file not shown.
After Width: | Height: | Size: 291 KiB |
28
controllerconfigs/controller_F510.ini
Normal file
28
controllerconfigs/controller_F510.ini
Normal file
@@ -0,0 +1,28 @@
|
||||
[Logitech Rumble Gamepad F510]
|
||||
VID=046D
|
||||
PID=C218
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
A=4,20
|
||||
B=4,10
|
||||
X=4,40
|
||||
Y=4,80
|
||||
Z=5,03
|
||||
L=5,04
|
||||
R=5,08
|
||||
Power=5,10
|
||||
S=5,20
|
||||
Left=4,06
|
||||
Down=4,04
|
||||
Right=4,02
|
||||
Up=4,00
|
||||
RightUp=4,01
|
||||
DownRight=4,03
|
||||
DownLeft=4,05
|
||||
UpLeft=4,07
|
||||
StickX=0
|
||||
StickY=1
|
||||
CStickX=2
|
||||
CStickY=3
|
||||
LAnalog=12
|
||||
RAnalog=13
|
@@ -0,0 +1,28 @@
|
||||
[Mayflash 3 in 1 Magic Joy Box]
|
||||
VID=0926
|
||||
PID=2526
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
A=1,01
|
||||
B=1,02
|
||||
X=1,04
|
||||
Y=1,08
|
||||
Z=1,40
|
||||
L=1,10
|
||||
R=1,20
|
||||
S=1,80
|
||||
Left=2,01
|
||||
Down=2,04
|
||||
Right=2,02
|
||||
Up=2,08
|
||||
RightUp=2,0A
|
||||
DownRight=2,06
|
||||
DownLeft= 2,05
|
||||
UpLeft=2,09
|
||||
StickX=3
|
||||
StickY=4
|
||||
CStickX=5
|
||||
CStickY=6
|
||||
LAnalog=7
|
||||
RAnalog=7
|
||||
Power=1,62
|
@@ -0,0 +1,27 @@
|
||||
[Logitech Thrustmaster Firestorm Dual Analog 2]
|
||||
VID=044F
|
||||
PID=B303
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
DigitalLR=1
|
||||
A=0,01
|
||||
B=0,02
|
||||
X=0,04
|
||||
Y=0,08
|
||||
Z=0,40
|
||||
L=0,20
|
||||
R=0,80
|
||||
Power=1,03
|
||||
S=1,02
|
||||
Left=2,60
|
||||
Down=2,40
|
||||
Right=2,20
|
||||
Up=2,00
|
||||
RightUp=2,10
|
||||
DownRight=2,30
|
||||
DownLeft=2,50
|
||||
UpLeft=2,70
|
||||
StickX=3
|
||||
StickY=4
|
||||
CStickX=5
|
||||
CStickY=6
|
31
controllerconfigs/controller_ps2.ini
Normal file
31
controllerconfigs/controller_ps2.ini
Normal file
@@ -0,0 +1,31 @@
|
||||
[PS2 Controller]
|
||||
VID=0810
|
||||
PID=0001
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
DigitalLR=1
|
||||
MultiIn=1
|
||||
MultiInValue=01
|
||||
Power=6,10
|
||||
A=5,20
|
||||
B=5,40
|
||||
X=5,10
|
||||
Y=5,80
|
||||
Z=6,08
|
||||
L=6,01
|
||||
R=6,02
|
||||
S=6,20
|
||||
Left=5,06
|
||||
Down=5,04
|
||||
Right=5,02
|
||||
Up=5,00
|
||||
RightUp=5,01
|
||||
DownRight=5,03
|
||||
DownLeft=5,05
|
||||
UpLeft=5,07
|
||||
StickX=3
|
||||
StickY=4
|
||||
CStickX=2
|
||||
CStickY=1
|
||||
LAnalog=0
|
||||
RAnalog=0
|
24
controllerconfigs/controller_ps3.ini
Normal file
24
controllerconfigs/controller_ps3.ini
Normal file
@@ -0,0 +1,24 @@
|
||||
[Dual Shock]
|
||||
VID=054C
|
||||
PID=0268
|
||||
Polltype=0
|
||||
DPAD=0
|
||||
Power=2,01
|
||||
A=3,80
|
||||
B=3,40
|
||||
X=3,20
|
||||
Y=3,10
|
||||
Z=3,08
|
||||
L=3,01
|
||||
R=3,02
|
||||
S=2,08
|
||||
Left=2,80
|
||||
Down=2,40
|
||||
Right=2,20
|
||||
Up=2,10
|
||||
StickX=6
|
||||
StickY=7
|
||||
CStickX=8
|
||||
CStickY=9
|
||||
LAnalog=12
|
||||
RAnalog=13
|
28
controllerconfigs/controller_ps4.ini
Normal file
28
controllerconfigs/controller_ps4.ini
Normal file
@@ -0,0 +1,28 @@
|
||||
[Dual Shock 4]
|
||||
VID=054C
|
||||
PID=05C4
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
A=5,20
|
||||
B=5,10
|
||||
X=5,40
|
||||
Y=5,80
|
||||
Z=6,02
|
||||
L=6,04
|
||||
R=6,08
|
||||
S=6,20
|
||||
Left=5,06
|
||||
Down=5,04
|
||||
Right=5,02
|
||||
Up=5,00
|
||||
RightUp=5,01
|
||||
DownRight=5,03
|
||||
DownLeft=5,05
|
||||
UpLeft=5,07
|
||||
StickX=1
|
||||
StickY=2
|
||||
CStickX=3
|
||||
CStickY=4
|
||||
LAnalog=8
|
||||
RAnalog=9
|
||||
Power=6,10
|
24
controllerconfigs/nintendont_triolinker1.ini
Normal file
24
controllerconfigs/nintendont_triolinker1.ini
Normal file
@@ -0,0 +1,24 @@
|
||||
[Trio Linker V1]
|
||||
VID=7701
|
||||
PID=0003
|
||||
Polltype=1
|
||||
DPAD=0
|
||||
DigitalLR=0
|
||||
A=0,04
|
||||
B=0,08
|
||||
X=0,02
|
||||
Y=0,01
|
||||
Z=0,80
|
||||
L=0,10
|
||||
R=0,20
|
||||
S=1,02
|
||||
Left=1,80
|
||||
Down=1,40
|
||||
Right=1,20
|
||||
Up=1,10
|
||||
StickX=2
|
||||
StickY=3
|
||||
CStickX=4
|
||||
CStickY=5
|
||||
LAnalog=0
|
||||
RAnalog=0
|
29
controllerconfigs/nintendont_wiiccprousb.ini
Normal file
29
controllerconfigs/nintendont_wiiccprousb.ini
Normal file
@@ -0,0 +1,29 @@
|
||||
[Mayflash CCPro USB Adapter]
|
||||
VID=0925
|
||||
PID=03E8
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
DigitalLR=1
|
||||
Power=2,02
|
||||
A=1,02
|
||||
B=1,08
|
||||
X=1,01
|
||||
Y=1,04
|
||||
Z=7,0F
|
||||
L=1,40
|
||||
R=1,80
|
||||
S=2,02
|
||||
Left=4,67
|
||||
Down=4,47
|
||||
Right=4,27
|
||||
Up=4,07
|
||||
RightUp=4,17
|
||||
DownRight=4,37
|
||||
DownLeft=4,57
|
||||
UpLeft=4,77
|
||||
StickX=3
|
||||
StickY=4
|
||||
CStickX=5
|
||||
CStickY=6
|
||||
LAnalog=11
|
||||
RAnalog=12
|
28
controllerconfigs/nintendont_wiiccusb.ini
Normal file
28
controllerconfigs/nintendont_wiiccusb.ini
Normal file
@@ -0,0 +1,28 @@
|
||||
[MayFlash Wii CC USB Adapter]
|
||||
VID=1D79
|
||||
PID=0301
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
Power=6,40
|
||||
A=5,20
|
||||
B=5,40
|
||||
X=5,10
|
||||
Y=5,80
|
||||
Z=6,08
|
||||
L=6,00
|
||||
R=6,02
|
||||
S=6,20
|
||||
Left=5,06
|
||||
Down=5,04
|
||||
Right=5,02
|
||||
Up=5,00
|
||||
RightUp=5,01
|
||||
DownRight=5,03
|
||||
DownLeft=5,05
|
||||
UpLeft=5,07
|
||||
StickX=2
|
||||
StickY=3
|
||||
CStickX=0
|
||||
CStickY=1
|
||||
LAnalog=20
|
||||
RAnalog=21
|
29
controllerconfigs/nintendont_wiiuprousb.ini
Normal file
29
controllerconfigs/nintendont_wiiuprousb.ini
Normal file
@@ -0,0 +1,29 @@
|
||||
[Mayflash WiiU Pro Controller Adapter - W009]
|
||||
VID=0079
|
||||
PID=1800
|
||||
Polltype=1
|
||||
DPAD=1
|
||||
DigitalLR=1
|
||||
A=1,04
|
||||
B=1,01
|
||||
X=1,08
|
||||
Y=1,02
|
||||
Z=1,20
|
||||
L=1,40
|
||||
R=1,80
|
||||
Power=2,04
|
||||
S=2,08
|
||||
Left=7,06
|
||||
Down=7,04
|
||||
Right=7,02
|
||||
Up=7,00
|
||||
RightUp=7,01
|
||||
DownRight=7,03
|
||||
DownLeft=7,05
|
||||
UpLeft=7,07
|
||||
StickX=3
|
||||
StickY=4
|
||||
CStickX=5
|
||||
CStickY=6
|
||||
LAnalog=0
|
||||
RAnalog=0
|
65
kernel/Config.c
Normal file
65
kernel/Config.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "Config.h"
|
||||
#include "ff.h"
|
||||
#include "debug.h"
|
||||
|
||||
NIN_CFG *ncfg = (NIN_CFG*)0x12002A18;
|
||||
|
||||
void ConfigInit( void )
|
||||
{
|
||||
FIL cfg;
|
||||
u32 read;
|
||||
|
||||
dbgprintf("CFGInit()\n");
|
||||
|
||||
if( f_open( &cfg, "/nincfg.bin", FA_OPEN_EXISTING|FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf("CFG:Failed to open config\n");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
f_read( &cfg, ncfg, sizeof(NIN_CFG), &read );
|
||||
sync_after_write(ncfg, sizeof(NIN_CFG));
|
||||
f_close( &cfg );
|
||||
|
||||
if( read != sizeof(NIN_CFG) )
|
||||
{
|
||||
dbgprintf("CFG:Failed to read config\n");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
if( IsWiiU )
|
||||
ncfg->Config |= NIN_CFG_HID;
|
||||
|
||||
if( (read32(0) >> 8) == 0x47504F ) // PSO 1&2 disable cheats/debugging
|
||||
{
|
||||
ncfg->Config &= ~(NIN_CFG_CHEATS|NIN_CFG_DEBUGGER|NIN_CFG_DEBUGWAIT);
|
||||
}
|
||||
}
|
||||
inline char *ConfigGetGamePath( void )
|
||||
{
|
||||
return ncfg->GamePath;
|
||||
}
|
||||
inline char *ConfigGetCheatPath( void )
|
||||
{
|
||||
return ncfg->CheatPath;
|
||||
}
|
||||
inline bool ConfigGetConfig( u32 Config )
|
||||
{
|
||||
return !!(ncfg->Config&Config);
|
||||
}
|
||||
inline u32 ConfigGetVideoMode( void )
|
||||
{
|
||||
return ncfg->VideoMode;
|
||||
}
|
||||
inline u32 ConfigGetLanguage( void )
|
||||
{
|
||||
return ncfg->Language;
|
||||
}
|
||||
inline u32 ConfigGetMaxPads(void)
|
||||
{
|
||||
return ncfg->MaxPads;
|
||||
}
|
||||
inline u32 ConfigGetGameID(void)
|
||||
{
|
||||
return ncfg->GameID;
|
||||
}
|
56
kernel/Config.h
Normal file
56
kernel/Config.h
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#include "global.h"
|
||||
#include "string.h"
|
||||
#include "syscalls.h"
|
||||
#include "global.h"
|
||||
#include "ipc.h"
|
||||
#include "common.h"
|
||||
#include "alloc.h"
|
||||
|
||||
#include "../common/include/CommonConfig.h"
|
||||
|
||||
enum Video {
|
||||
NTSC,
|
||||
PAL,
|
||||
MPAL,
|
||||
};
|
||||
|
||||
enum Sound { Monoral,
|
||||
Stereo,
|
||||
Surround
|
||||
};
|
||||
|
||||
enum AspectRatio { _4to3,
|
||||
_16to9
|
||||
};
|
||||
|
||||
enum GeneralONOFF { Off,
|
||||
On
|
||||
};
|
||||
|
||||
enum SystemLanguage { Japanese,
|
||||
English,
|
||||
German,
|
||||
French,
|
||||
Spanish,
|
||||
Italian,
|
||||
Dutch,
|
||||
ChineseSimple,
|
||||
ChineseTraditional,
|
||||
Korean
|
||||
};
|
||||
|
||||
void ConfigInit( void );
|
||||
char *ConfigGetGamePath( void );
|
||||
char *ConfigGetCheatPath( void );
|
||||
bool ConfigGetConfig( u32 Config );
|
||||
u32 ConfigGetVideoMode( void );
|
||||
u32 ConfigGetLanguage( void );
|
||||
u32 ConfigGetMaxPads(void);
|
||||
u32 ConfigGetGameID(void);
|
||||
//bool IsWiiU;
|
||||
|
||||
#endif
|
423
kernel/DI.c
Normal file
423
kernel/DI.c
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
|
||||
Nintendont (Kernel) - Playing Gamecubes in Wii mode on a Wii U
|
||||
|
||||
Copyright (C) 2013 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#include "DI.h"
|
||||
#include "string.h"
|
||||
#include "syscalls.h"
|
||||
#include "global.h"
|
||||
#include "ipc.h"
|
||||
#include "common.h"
|
||||
#include "alloc.h"
|
||||
#include "StreamADPCM.h"
|
||||
#include "ff.h"
|
||||
#include "dol.h"
|
||||
#include "Config.h"
|
||||
#include "Patch.h"
|
||||
#include "FST.h"
|
||||
|
||||
#ifndef DEBUG_DI
|
||||
#define dbgprintf(...)
|
||||
#else
|
||||
extern int dbgprintf( const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
u32 StreamBufferSize= 0x1E00000;
|
||||
u32 StreamBuffer = 0x11200000+0x60;
|
||||
u32 Streaming = 0;
|
||||
u32 StreamOffset = 0;
|
||||
u32 StreamDiscOffset= 0;
|
||||
s32 StreamSize = 0;
|
||||
u32 StreamRAMOffset = 0;
|
||||
u32 StreamTimer = 0;
|
||||
u32 StreamStopEnd = 0;
|
||||
u32 DiscChangeIRQ = 0;
|
||||
|
||||
FIL GameFile;
|
||||
|
||||
static char GamePath[256] ALIGNED(32);
|
||||
|
||||
extern u32 Region;
|
||||
extern u32 FSTMode;
|
||||
|
||||
void DIinit( void )
|
||||
{
|
||||
u32 read;
|
||||
|
||||
dbgprintf("DIInit()\n");
|
||||
|
||||
s32 ret = f_open( &GameFile, ConfigGetGamePath(), FA_READ|FA_OPEN_EXISTING );
|
||||
if( ret != FR_OK )
|
||||
{
|
||||
_sprintf( GamePath, "%s", ConfigGetGamePath() );
|
||||
|
||||
//Try to switch to FST mode
|
||||
if( !FSTInit(GamePath) )
|
||||
{
|
||||
dbgprintf("Failed to open:%s Error:%u\n", ConfigGetGamePath(), ret );
|
||||
Shutdown();
|
||||
}
|
||||
} else {
|
||||
f_lseek( &GameFile, 0x458 );
|
||||
f_read( &GameFile, &Region, sizeof(u32), &read );
|
||||
}
|
||||
|
||||
memset32( (void*)DI_BASE, 0xdeadbeef, 0x30 );
|
||||
memset32( (void*)DI_SHADOW, 0, 0x30 );
|
||||
|
||||
sync_after_write( (void*)DI_BASE, 0x60 );
|
||||
|
||||
write32( DIP_IMM, 0 ); //reset errors
|
||||
write32( DIP_STATUS, 0x2E );
|
||||
write32( DIP_CMD_0, 0xE3000000 ); //spam stop motor
|
||||
}
|
||||
void DIChangeDisc( u32 DiscNumber )
|
||||
{
|
||||
f_close( &GameFile );
|
||||
|
||||
u32 read, i;
|
||||
char str[256] __attribute__((aligned(0x20)));
|
||||
|
||||
memset32( str, 0, 256 );
|
||||
|
||||
_sprintf( str, "%s", ConfigGetGamePath() );
|
||||
|
||||
//search the string backwards for '/'
|
||||
for( i=strlen(str); i > 0; --i )
|
||||
if( str[i] == '/' )
|
||||
break;
|
||||
i++;
|
||||
|
||||
if( DiscNumber == 0 )
|
||||
_sprintf( str+i, "game.iso" );
|
||||
else
|
||||
_sprintf( str+i, "disc2.iso" );
|
||||
|
||||
dbgprintf("New Gamepath:\"%s\"\n", str );
|
||||
|
||||
s32 ret = f_open( &GameFile, str, FA_READ|FA_OPEN_EXISTING );
|
||||
if( ret != FR_OK )
|
||||
{
|
||||
dbgprintf("Failed to open:%s Error:%u\n", str, ret );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
f_lseek( &GameFile, 0 );
|
||||
f_read( &GameFile, (void*)0, 0x20, &read );
|
||||
|
||||
f_lseek( &GameFile, 0 );
|
||||
f_read( &GameFile, str, 0x400, &read );
|
||||
|
||||
dbgprintf("DIP:Loading game %.6s: %s\n", str, (char *)(str+0x20));
|
||||
|
||||
f_lseek( &GameFile, 0x420 );
|
||||
f_read( &GameFile, str, 0x40, &read );
|
||||
|
||||
free(str);
|
||||
|
||||
}
|
||||
void DIUpdateRegisters( void )
|
||||
{
|
||||
u32 read,i;
|
||||
u32 DIOK = 0,DIcommand;
|
||||
|
||||
u32 *DInterface = (u32*)(DI_BASE);
|
||||
u32 *DInterfaceS = (u32*)(DI_SHADOW);
|
||||
|
||||
sync_before_read( (void*)DI_BASE, 0x60 );
|
||||
|
||||
if( read32(DI_CONTROL) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SCONTROL, read32(DI_CONTROL) & 3 );
|
||||
|
||||
*(vu32*)DI_SSTATUS &= ~0x14;
|
||||
|
||||
write32( DI_CONTROL, 0xdeadbeef );
|
||||
sync_after_write( (void*)DI_BASE, 0x60 );
|
||||
|
||||
if( read32(DI_SCONTROL) & 1 )
|
||||
{
|
||||
for( i=2; i < 9; ++i )
|
||||
{
|
||||
if( DInterface[i] != 0xdeadbeef )
|
||||
{
|
||||
DInterfaceS[i] = DInterface[i];
|
||||
DInterface[i] = 0xdeadbeef;
|
||||
}
|
||||
}
|
||||
DIcommand = read32(DI_SCMD_0) >> 24;
|
||||
switch( DIcommand )
|
||||
{
|
||||
default:
|
||||
{
|
||||
dbgprintf("DI: Unknown command:%02X\n", DIcommand );
|
||||
|
||||
for( i = 0; i < 0x30; i+=4 )
|
||||
dbgprintf("0x%08X:0x%08X\t0x%08X\n", i, read32( DI_BASE + i ), read32( DI_SHADOW + i ) );
|
||||
dbgprintf("\n");
|
||||
|
||||
memset32( (void*)DI_BASE, 0xdeadbeef, 0x30 );
|
||||
memset32( (void*)(DI_SHADOW), 0, 0x30 );
|
||||
|
||||
write32( DI_SCONFIG, 0xFF );
|
||||
write32( DI_SCOVER, 0 );
|
||||
|
||||
Shutdown();
|
||||
|
||||
} break;
|
||||
case 0xE1: // play Audio Stream
|
||||
{
|
||||
switch( (read32(DI_SCMD_0) >> 16 ) & 0xFF )
|
||||
{
|
||||
case 0x00:
|
||||
{
|
||||
if( read32(DI_SCMD_1) == 0 && read32(DI_SCMD_2) == 0 )
|
||||
{
|
||||
StreamStopEnd = 1;
|
||||
dbgprintf("DIP:DVDPrepareStreamAbsAsync( %08X, %08X )\n", read32(DI_SCMD_1), read32(DI_SCMD_2) );
|
||||
} else {
|
||||
|
||||
StreamDiscOffset= read32(DI_SCMD_1)<<2;
|
||||
StreamSize = read32(DI_SCMD_2);
|
||||
StreamOffset = 0;
|
||||
Streaming = 1;
|
||||
StreamStopEnd = 0;
|
||||
StreamTimer = read32(HW_TIMER);
|
||||
|
||||
dbgprintf("DIP:Streaming %ds of audio...\n", StreamSize / 32 * 28 / 48043 );
|
||||
dbgprintf("DIP:Size:%u\n", StreamSize );
|
||||
dbgprintf("DIP:Samples:%u\n", StreamSize / (SAMPLES_PER_BLOCK*sizeof(u16)) );
|
||||
#ifdef AUDIOSTREAM
|
||||
f_lseek( &GameFile, StreamDiscOffset );
|
||||
ret = f_read( &GameFile, (void*)(StreamBuffer+0x1000), StreamSize, &read );
|
||||
|
||||
if( read != StreamSize )
|
||||
{
|
||||
dbgprintf("DIP:Failed to read:%u(%u) Error:%u\n", StreamSize, read, ret );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
u32 SrcOff = 0x1000;
|
||||
u32 DstOff = 0;
|
||||
|
||||
unsigned int samples = StreamSize / 32;
|
||||
|
||||
while(samples)
|
||||
{
|
||||
transcode_frame( (char*)(StreamBuffer + SrcOff), 0, (char*)(StreamBuffer + DstOff) );
|
||||
DstOff += 16;
|
||||
|
||||
transcode_frame( (char*)(StreamBuffer + SrcOff), 1, (char*)(StreamBuffer + DstOff) );
|
||||
SrcOff += ONE_BLOCK_SIZE;
|
||||
DstOff += 16;
|
||||
|
||||
samples--;
|
||||
|
||||
// decode_ngc_dtk( (u8*)(0x11000000 + SrcOff), (u16*)(StreamBuffer + DstOff), 1, 0, 28, 0 );
|
||||
// decode_ngc_dtk( (u8*)buf+i*32, (s16*)(StreamBuffer + DstOff + 2), 2, 0, 28, 1 );
|
||||
|
||||
// DecodeBlock( (s16*)(StreamBuffer + DstOff), (u8*)(StreamBuffer + 0x1300000 + SrcOff) );
|
||||
|
||||
if( DstOff >= StreamBufferSize )
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *header = (uint8_t*)0x11200000;
|
||||
memset32(header, 0, sizeof(header));
|
||||
|
||||
// 0-3: sample count
|
||||
*(vu32*)(header+0) = samples;
|
||||
|
||||
// 4-7: nibble count
|
||||
*(vu32*)(header+4) = samples/14*16;
|
||||
|
||||
// 8-11: sample rate
|
||||
*(vu32*)(header+8) = 48000;
|
||||
|
||||
// 12-13: loop flag (0)
|
||||
|
||||
// 14-15: format (0: ADPCM)
|
||||
|
||||
// 16-19: loop start, 20-23: loop end (0)
|
||||
|
||||
// 24-27: ca ("current" nibble offset)
|
||||
*(vu32*)(header+24) = 2;
|
||||
|
||||
// 28-59 filter coefficients
|
||||
{
|
||||
// these are the fixed filters used by XA
|
||||
const uint16_t coef[16] = {
|
||||
0, 0,
|
||||
0x3c, 0,
|
||||
0x73, -0x34,
|
||||
0x62, -0x37
|
||||
};
|
||||
|
||||
for (j = 0; j < 16; j+=2)
|
||||
{
|
||||
u32 val = coef[j+1]<<5;
|
||||
val|= (coef[j]<<5) << 16;
|
||||
|
||||
*(vu32*)(header+28+j*2) = val;
|
||||
}
|
||||
}
|
||||
|
||||
*(vu32*)(header+60) = *(vu32*)(StreamBuffer)<<16;
|
||||
|
||||
|
||||
//sync_after_write( (void*)StreamBuffer, StreamBufferSize );
|
||||
|
||||
//sync_before_read( (void*)0, 0x20 );
|
||||
|
||||
*(vu32*)(0x14) = StreamBuffer|0xD0000000;
|
||||
*(vu32*)(0x18) = (StreamBuffer+DstOff)|0xD0000000;
|
||||
|
||||
//sync_after_write( (void*)0, 0x20 );
|
||||
#endif
|
||||
|
||||
dbgprintf("DIP:Streaming %ds of audio...\n", StreamSize / 32 * 28 / 48043 );
|
||||
dbgprintf("DIP:DVDPrepareStreamAbsAsync( %08X, %08X )\n", StreamDiscOffset, StreamSize );
|
||||
}
|
||||
} break;
|
||||
case 0x01:
|
||||
{
|
||||
StreamDiscOffset= 0;
|
||||
StreamSize = 0;
|
||||
StreamOffset = 0;
|
||||
Streaming = 0;
|
||||
|
||||
dbgprintf("DIP:DVDCancelStreamAsync()\n");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
dbgprintf("DIP:DVDStream(%d)\n", (read32(DI_SCMD_0) >> 16 ) & 0xFF );
|
||||
} break;
|
||||
}
|
||||
|
||||
DIOK = 2;
|
||||
|
||||
} break;
|
||||
case 0xE2: // request Audio Status
|
||||
{
|
||||
switch( read32(DI_SCMD_0)<<8 )
|
||||
{
|
||||
case 0x00000000: // Streaming?
|
||||
{
|
||||
write32( DI_SIMM, Streaming );
|
||||
} break;
|
||||
case 0x01000000: // What is the current address?
|
||||
{
|
||||
dbgprintf("DIP:StreamInfo:Cur:%08X End:%08X\n", StreamOffset, StreamSize );
|
||||
write32( DI_SIMM, ((StreamDiscOffset+StreamOffset) >> 2) & (~0x1FFF) );
|
||||
} break;
|
||||
case 0x02000000: // disc offset of file
|
||||
{
|
||||
write32( DI_SIMM, StreamDiscOffset>>2 );
|
||||
} break;
|
||||
case 0x03000000: // Size of file
|
||||
{
|
||||
write32( DI_SIMM, StreamSize );
|
||||
} break;
|
||||
}
|
||||
|
||||
// dbgprintf("DIP:DVDLowAudioGetConfig( %d, %08X )\n", (read32(DI_SCMD_0)>>16)&0xFF, read32(DI_SIMM) );
|
||||
|
||||
DIOK = 2;
|
||||
|
||||
} break;
|
||||
case 0xE3: // stop Motor
|
||||
{
|
||||
dbgprintf("DIP:DVDLowStopMotor()\n");
|
||||
u32 CDiscNumber = (read32(4) << 16 ) >> 24;
|
||||
dbgprintf("DIP:Current disc number:%u\n", CDiscNumber + 1 );
|
||||
|
||||
DIChangeDisc( CDiscNumber ^ 1 );
|
||||
|
||||
DiscChangeIRQ = 1;
|
||||
|
||||
DIOK = 2;
|
||||
|
||||
write32( HW_TIMER, 0 );
|
||||
|
||||
} break;
|
||||
case 0xE4: // DVD Audio disable
|
||||
{
|
||||
DIOK = 2;
|
||||
|
||||
} break;
|
||||
case 0xA7:
|
||||
case 0xA9:
|
||||
//dbgprintf("DIP:Async!\n");
|
||||
case 0xA8:
|
||||
{
|
||||
u32 Buffer = P2C(read32(DI_SDMA_ADR));
|
||||
u32 Length = read32(DI_SCMD_2);
|
||||
u32 Offset = read32(DI_SCMD_1) << 2;
|
||||
dbgprintf( "DIP:DVDRead%02X( 0x%08x, 0x%08x, 0x%08x )\n", read32(DI_SCMD_0) >> 24, Offset, Length, Buffer|0x80000000 );
|
||||
memset32((void*)0x12100000, 0, Length);
|
||||
if( FSTMode )
|
||||
FSTRead( GamePath, (char*)0x12100000, Length, Offset );
|
||||
else
|
||||
{
|
||||
if( GameFile.fptr != Offset )
|
||||
f_lseek( &GameFile, Offset );
|
||||
|
||||
s32 ret = f_read( &GameFile, (void*)0x12100000, Length, &read );
|
||||
// dbgprintf( "%d\n", read );
|
||||
if( ret != FR_OK )
|
||||
{
|
||||
dbgprintf( "f_read failed(%u,%u):%d\n", Length, read, ret );
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
memcpy((void*)Buffer, (void*)0x12100000, Length);
|
||||
DoPatches( (char*)Buffer, Length, Offset );
|
||||
sync_after_write( (void*)Buffer, Length );
|
||||
if( DIcommand == 0xA7 )
|
||||
{
|
||||
DIOK = 2;
|
||||
} else {
|
||||
DIOK = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( DIOK )
|
||||
{
|
||||
//write32( DI_SDMA_LEN, 0 );
|
||||
set32( DI_SSTATUS, 0x3A );
|
||||
sync_after_write( (void*)DI_BASE, 0x60 );
|
||||
|
||||
if( DIOK == 2 )
|
||||
{
|
||||
//wait_for_ppc(5); //wait so game expects it
|
||||
write32( DIP_CONTROL, 1 ); //start transfer so game gets its data
|
||||
while( read32(DIP_CONTROL) & 1 ) ;
|
||||
}
|
||||
write32(DI_SCONTROL, 0);
|
||||
//while( read32(DI_SCONTROL) & 1 )
|
||||
// clear32( DI_SCONTROL, 1 );
|
||||
}
|
||||
}
|
||||
sync_after_write( (void*)DI_BASE, 0x60 );
|
||||
}
|
||||
else //give the hid thread some time
|
||||
udelay(10);
|
||||
return;
|
||||
}
|
72
kernel/DI.h
Normal file
72
kernel/DI.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef __DI_H__
|
||||
#define __DI_H__
|
||||
|
||||
#include "global.h"
|
||||
#include "ff.h"
|
||||
|
||||
#define DI_BASE 0x00002F00
|
||||
|
||||
#define DI_STATUS (DI_BASE+0x00)
|
||||
#define DI_COVER (DI_BASE+0x04)
|
||||
#define DI_CMD_0 (DI_BASE+0x08)
|
||||
#define DI_CMD_1 (DI_BASE+0x0C)
|
||||
#define DI_CMD_2 (DI_BASE+0x10)
|
||||
#define DI_DMA_ADR (DI_BASE+0x14)
|
||||
#define DI_DMA_LEN (DI_BASE+0x18)
|
||||
#define DI_CONTROL (DI_BASE+0x1C)
|
||||
#define DI_IMM (DI_BASE+0x20)
|
||||
#define DI_CONFIG (DI_BASE+0x24)
|
||||
|
||||
#define DI_SHADOW (DI_BASE + 0x30)
|
||||
|
||||
#define DI_SSTATUS (DI_SHADOW+0x00)
|
||||
#define DI_SCOVER (DI_SHADOW+0x04)
|
||||
#define DI_SCMD_0 (DI_SHADOW+0x08)
|
||||
#define DI_SCMD_1 (DI_SHADOW+0x0C)
|
||||
#define DI_SCMD_2 (DI_SHADOW+0x10)
|
||||
#define DI_SDMA_ADR (DI_SHADOW+0x14)
|
||||
#define DI_SDMA_LEN (DI_SHADOW+0x18)
|
||||
#define DI_SCONTROL (DI_SHADOW+0x1C)
|
||||
#define DI_SIMM (DI_SHADOW+0x20)
|
||||
#define DI_SCONFIG (DI_SHADOW+0x24)
|
||||
|
||||
#define DIP_BASE 0x0D806000
|
||||
|
||||
#define DIP_STATUS (DIP_BASE+0x00)
|
||||
#define DIP_COVER (DIP_BASE+0x04)
|
||||
#define DIP_CMD_0 (DIP_BASE+0x08)
|
||||
#define DIP_CMD_1 (DIP_BASE+0x0C)
|
||||
#define DIP_CMD_2 (DIP_BASE+0x10)
|
||||
#define DIP_DMA_ADR (DIP_BASE+0x14)
|
||||
#define DIP_DMA_LEN (DIP_BASE+0x18)
|
||||
#define DIP_CONTROL (DIP_BASE+0x1C)
|
||||
#define DIP_IMM (DIP_BASE+0x20)
|
||||
#define DIP_CONFIG (DIP_BASE+0x24)
|
||||
|
||||
#define DMA_READ 3
|
||||
#define IMM_READ 1
|
||||
|
||||
enum GameRegion
|
||||
{
|
||||
JAP=0,
|
||||
USA,
|
||||
EUR,
|
||||
KOR,
|
||||
ASN,
|
||||
LTN,
|
||||
UNK,
|
||||
ALL,
|
||||
};
|
||||
|
||||
extern u32 Streaming;
|
||||
extern u32 StreamOffset;
|
||||
extern s32 StreamSize;
|
||||
extern u32 StreamTimer;
|
||||
extern vu32 SDisInit;
|
||||
extern u32 DiscChangeIRQ;
|
||||
|
||||
void DIinit( void );
|
||||
void DIChangeDisc( u32 DiscNumber );
|
||||
void DIUpdateRegisters( void );
|
||||
|
||||
#endif
|
515
kernel/ES.c
Normal file
515
kernel/ES.c
Normal file
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
|
||||
Nintendont (Kernel) - Playing Gamecubes in Wii mode on a Wii U
|
||||
|
||||
Copyright (C) 2013 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#include "ES.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifndef DEBUG_ES
|
||||
#define dbgprintf(...)
|
||||
#else
|
||||
extern int dbgprintf( const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
char *path = (char*)NULL;
|
||||
u32 *size = (u32*)NULL;
|
||||
u64 *iTitleID = (u64*)NULL;
|
||||
|
||||
static u64 TitleID ALIGNED(32);
|
||||
static u32 KernelVersion ALIGNED(32);
|
||||
|
||||
static u8 *DITicket;
|
||||
|
||||
static u8 *CNTMap;
|
||||
static u32 *CNTSize;
|
||||
static u32 *CNTMapDirty;
|
||||
|
||||
static u64 *TTitles;
|
||||
|
||||
u64 *TTitlesO;
|
||||
u32 TOCount;
|
||||
u32 TOCountDirty;
|
||||
|
||||
u32 *KeyID = (u32*)NULL;
|
||||
|
||||
TitleMetaData *iTMD = (TitleMetaData *)NULL; //used for information during title import
|
||||
static u8 *iTIK = (u8 *)NULL; //used for information during title import
|
||||
|
||||
u16 TitleVersion;
|
||||
|
||||
// General ES functions
|
||||
|
||||
u32 ES_Init( u8 *MessageHeap )
|
||||
{
|
||||
//Used in Ioctlvs
|
||||
path = (char*)malloca( 0x40, 32 );
|
||||
size = (u32*) malloca( sizeof(u32), 32 );
|
||||
iTitleID = (u64*) malloca( sizeof(u64), 32 );
|
||||
|
||||
CNTMap = (u8*)NULL;
|
||||
DITicket = (u8*)NULL;
|
||||
KeyID = (u32*)NULL;
|
||||
|
||||
CNTSize = (u32*)malloca( 4, 32 );
|
||||
CNTMapDirty = (u32*)malloca( 4, 32 );
|
||||
*CNTMapDirty= 1;
|
||||
|
||||
TTitles = (u64*)NULL;
|
||||
TTitlesO = (u64*)NULL;
|
||||
|
||||
TOCount = 0;
|
||||
TOCountDirty = 0;
|
||||
TOCountDirty = 1;
|
||||
|
||||
u32 MessageQueue = mqueue_create( MessageHeap, 1 );
|
||||
|
||||
device_register( "/dev/es", MessageQueue );
|
||||
|
||||
u32 pid = GetPID();
|
||||
SetUID( pid, 0 );
|
||||
SetGID( pid, 0 );
|
||||
#ifdef DEBUG_ES
|
||||
u32 version = KernelGetVersion();
|
||||
dbgprintf("ES:KernelVersion:%08X, %d\n", version, (version<<8)>>0x18 );
|
||||
#endif
|
||||
ES_BootSystem();
|
||||
|
||||
dbgprintf("ES:TitleID:%08x-%08x version:%d\n", (u32)((TitleID)>>32), (u32)(TitleID), TitleVersion );
|
||||
|
||||
return MessageQueue;
|
||||
}
|
||||
|
||||
s32 ES_BootSystem( void )
|
||||
{
|
||||
char *path = (char*)malloca( 0x40, 32 );
|
||||
u32 *size = (u32*)malloca( sizeof(u32), 32 );
|
||||
|
||||
u32 IOSVersion = 55;
|
||||
|
||||
dbgprintf("ES:Loading IOS%d ...\n", IOSVersion );
|
||||
|
||||
//Load TMD of the requested IOS and build KernelVersion
|
||||
_sprintf( path, "/title/00000001/%08x/content/title.tmd", IOSVersion );
|
||||
|
||||
TitleMetaData *TMD = (TitleMetaData *)NANDLoadFile( path, size );
|
||||
if( TMD == NULL )
|
||||
{
|
||||
dbgprintf("ES:Failed to open:\"%s\":%d\n", path, *size );
|
||||
free( path );
|
||||
free( size );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
KernelVersion = TMD->TitleVersion;
|
||||
KernelVersion|= IOSVersion<<16;
|
||||
KernelSetVersion( KernelVersion );
|
||||
#ifdef DEBUG_ES
|
||||
u32 version = KernelGetVersion();
|
||||
dbgprintf("ES:KernelVersion:%08X, %d\n", version, (version<<8)>>0x18 );
|
||||
#endif
|
||||
free( TMD );
|
||||
#ifndef NINTENDONT_USB
|
||||
|
||||
s32 r = LoadModules( IOSVersion );
|
||||
dbgprintf("ES:ES_LoadModules(%d):%d\n", IOSVersion, r );
|
||||
if( r < 0 )
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
#endif
|
||||
free( path );
|
||||
free( size );
|
||||
|
||||
#ifndef NINTENDONT_USB
|
||||
return r;
|
||||
#else
|
||||
return IOSVersion;
|
||||
#endif
|
||||
|
||||
}
|
||||
s32 LoadModules( u32 IOSVersion )
|
||||
{
|
||||
//used later for decrypted
|
||||
KeyID = (u32*)malloca( sizeof(u32), 0x40 );
|
||||
char *path = malloca( 0x70, 0x40 );
|
||||
|
||||
s32 r=0;
|
||||
int i;
|
||||
|
||||
//load TMD
|
||||
_sprintf( path, "/title/00000001/%08x/content/title.tmd", IOSVersion );
|
||||
|
||||
u32 *size = (u32*)malloca( sizeof(u32), 0x40 );
|
||||
TitleMetaData *TMD = (TitleMetaData*)NANDLoadFile( path, size );
|
||||
if( TMD == NULL )
|
||||
{
|
||||
free( path );
|
||||
return *size;
|
||||
}
|
||||
|
||||
if( TMD->ContentCount == 3 ) // STUB detected!
|
||||
{
|
||||
dbgprintf("ES:STUB IOS detected, falling back to IOS35\n");
|
||||
free( path );
|
||||
free( KeyID );
|
||||
free( size );
|
||||
return LoadModules( 35 );
|
||||
}
|
||||
|
||||
dbgprintf("ES:ContentCount:%d\n", TMD->ContentCount );
|
||||
|
||||
for( i=0; i < TMD->ContentCount; ++i )
|
||||
{
|
||||
//Don't load boot module
|
||||
if( TMD->BootIndex == TMD->Contents[i].Index )
|
||||
continue;
|
||||
|
||||
|
||||
#ifdef NINTENDONT_USB
|
||||
if( TMD->Contents[i].Index == 4 ) // SDI
|
||||
continue;
|
||||
#endif
|
||||
/*
|
||||
1 di
|
||||
2 oh0
|
||||
3 oh1
|
||||
4 sdi
|
||||
5 SO
|
||||
6 KD
|
||||
7 WD
|
||||
8 WL
|
||||
9 NCD
|
||||
10 ETH
|
||||
11 STM
|
||||
12 nothing? hid?
|
||||
13 SSL
|
||||
*/
|
||||
if( TMD->Contents[i].Index == 1 ) // DI
|
||||
continue;
|
||||
if( TMD->Contents[i].Index == 5 ) // SO
|
||||
continue;
|
||||
if( TMD->Contents[i].Index == 6 ) // KD
|
||||
continue;
|
||||
if( TMD->Contents[i].Index == 7 ) // WD
|
||||
continue;
|
||||
if( TMD->Contents[i].Index == 8 ) // WL
|
||||
continue;
|
||||
if( TMD->Contents[i].Index == 10 ) // ETH
|
||||
continue;
|
||||
if( TMD->Contents[i].Index == 13 ) // SSL
|
||||
continue;
|
||||
|
||||
//check if shared!
|
||||
if( TMD->Contents[i].Type & CONTENT_SHARED )
|
||||
{
|
||||
u32 ID = GetSharedContentID( TMD->Contents[i].SHA1 );
|
||||
|
||||
if( (s32)ID == ES_FATAL )
|
||||
{
|
||||
dbgprintf("ES:Fatal error: required shared content not found!\n");
|
||||
dbgprintf("Hash:\n");
|
||||
hexdump( TMD->Contents[i].SHA1, 0x14 );
|
||||
Shutdown();
|
||||
|
||||
} else {
|
||||
_sprintf( path, "/shared1/%08x.app", ID );
|
||||
}
|
||||
|
||||
} else {
|
||||
_sprintf( path, "/title/00000001/%08x/content/%08x.app", IOSVersion, TMD->Contents[i].ID );
|
||||
}
|
||||
|
||||
dbgprintf("ES:Loaded Module(%d):\"%s\"\n", i, path );
|
||||
r = LoadModule( path );
|
||||
if( r < 0 )
|
||||
{
|
||||
dbgprintf("ES:Fatal error: module failed to start!\n");
|
||||
dbgprintf("ret:%d\n", r );
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
free( size );
|
||||
free( TMD );
|
||||
free( path );
|
||||
|
||||
thread_set_priority( 0, 0x50 );
|
||||
mdelay(500); //devices finish init
|
||||
return ES_SUCCESS;
|
||||
}
|
||||
u64 GetTitleID( void )
|
||||
{
|
||||
return TitleID;
|
||||
}
|
||||
void iCleanUpTikTMD( void )
|
||||
{
|
||||
if( iTMD != NULL )
|
||||
{
|
||||
free( iTMD );
|
||||
iTMD = NULL;
|
||||
}
|
||||
if( iTIK != NULL )
|
||||
{
|
||||
free( iTIK );
|
||||
iTIK = (u8*)NULL;
|
||||
}
|
||||
}
|
||||
void iGetTMDView( TitleMetaData *TMD, u8 *oTMDView )
|
||||
{
|
||||
u32 TMDViewSize = (TMD->ContentCount<<4) + 0x5C;
|
||||
u8 *TMDView = (u8*)malloca( TMDViewSize, 32 );
|
||||
|
||||
memset32( TMDView, 0, TMDViewSize );
|
||||
|
||||
TMDView[0] = TMD->Version;
|
||||
|
||||
*(u64*)(TMDView+0x04) = TMD->SystemVersion;
|
||||
*(u64*)(TMDView+0x0C) = TMD->TitleID;
|
||||
*(u32*)(TMDView+0x14) = TMD->TitleType;
|
||||
*(u16*)(TMDView+0x18) = TMD->GroupID;
|
||||
|
||||
memcpy( TMDView+0x1A, (u8*)TMD + 0x19A, 0x3E ); // Region info
|
||||
|
||||
*(u16*)(TMDView+0x58) = TMD->TitleVersion;
|
||||
*(u16*)(TMDView+0x5A) = TMD->ContentCount;
|
||||
|
||||
if( TMD->ContentCount ) // Contents
|
||||
{
|
||||
int i;
|
||||
for( i=0; i < TMD->ContentCount; ++i )
|
||||
{
|
||||
*(u32*)(TMDView + i * 16 + 0x5C) = TMD->Contents[i].ID;
|
||||
*(u16*)(TMDView + i * 16 + 0x60) = TMD->Contents[i].Index;
|
||||
*(u16*)(TMDView + i * 16 + 0x62) = TMD->Contents[i].Type;
|
||||
*(u64*)(TMDView + i * 16 + 0x64) = TMD->Contents[i].Size;
|
||||
}
|
||||
}
|
||||
|
||||
////region free hack
|
||||
// memset8( TMDView+0x1E, 0, 16 );
|
||||
// *(u8*) (TMDView+0x21) = 0x0F;
|
||||
// *(u16*)(TMDView+0x1C) = 3;
|
||||
////-
|
||||
|
||||
memcpy( oTMDView, TMDView, TMDViewSize );
|
||||
free( TMDView );
|
||||
}
|
||||
s32 GetTMDView( u64 *TitleID, u8 *oTMDView )
|
||||
{
|
||||
char *path = (char*)malloca( 0x40, 32 );
|
||||
u32 *size = (u32*) malloca( 4, 32 );
|
||||
|
||||
_sprintf( path, "/title/%08x/%08x/content/title.tmd", (u32)(*TitleID>>32), (u32)*TitleID );
|
||||
|
||||
u8 *data = (u8*)NANDLoadFile( path, size );
|
||||
if( data == NULL )
|
||||
{
|
||||
free( path );
|
||||
free( size );
|
||||
return ES_FATAL;
|
||||
}
|
||||
|
||||
iGetTMDView( (TitleMetaData *)data, oTMDView );
|
||||
|
||||
free( path );
|
||||
free( size );
|
||||
|
||||
return ES_SUCCESS;
|
||||
}
|
||||
s32 GetUID( u64 *TitleID, u16 *UID )
|
||||
{
|
||||
char *path = (char*)malloca( 0x40, 32 );
|
||||
u32 *size = (u32*) malloca( sizeof(u32), 32 );
|
||||
//char path[0x40] ALIGNED(32);
|
||||
//u32 size[sizeof(u32)] ALIGNED(32);
|
||||
|
||||
_sprintf( path, "/sys/uid.sys");
|
||||
|
||||
UIDSYS *uid = (UIDSYS *)NANDLoadFile( path, size );
|
||||
if( uid == NULL )
|
||||
{
|
||||
free( path );
|
||||
dbgprintf("ES:ESP_GetUID():Could not open \"/sys/uid.sys\"! Error:%d\n", *size );
|
||||
return *size;
|
||||
}
|
||||
|
||||
*UID = 0xdead;
|
||||
|
||||
u32 i;
|
||||
for( i=0; i * 12 < *size; ++i )
|
||||
{
|
||||
if( uid[i].TitleID == *TitleID )
|
||||
{
|
||||
*UID = uid[i].GroupID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free( uid );
|
||||
|
||||
if( *UID == 0xdead ) // Title has no UID yet, add it
|
||||
{
|
||||
_sprintf( path, "/sys/uid.sys");
|
||||
|
||||
s32 fd = IOS_Open( path, 2 );
|
||||
if( fd < 0 )
|
||||
{
|
||||
free( path );
|
||||
free( size );
|
||||
return fd;
|
||||
}
|
||||
|
||||
// 1-2 UID: 0x1000
|
||||
|
||||
*(vu64*)(path) = *TitleID;
|
||||
*(vu32*)(path+8)= 0x00001000+*size/12+1;
|
||||
|
||||
*UID = 0x1000+*size/12+1;
|
||||
|
||||
dbgprintf("ES:TitleID not found adding new UID:0x%04x\n", *UID );
|
||||
|
||||
s32 r = IOS_Seek( fd, 0, SEEK_END );
|
||||
if( r < 0 )
|
||||
{
|
||||
free( path );
|
||||
free( size );
|
||||
IOS_Close( fd );
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
r = IOS_Write( fd, path, 12 );
|
||||
if( r != 12 || r < 0 )
|
||||
{
|
||||
free( path );
|
||||
free( size );
|
||||
IOS_Close( fd );
|
||||
return r;
|
||||
}
|
||||
|
||||
IOS_Close( fd );
|
||||
}
|
||||
|
||||
free( path );
|
||||
free( size );
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 ES_CheckSharedContent( void *ContentHash )
|
||||
{
|
||||
if( *CNTMapDirty )
|
||||
{
|
||||
dbgprintf("ES:Loading content.map...\n");
|
||||
|
||||
if( CNTMap != NULL )
|
||||
{
|
||||
free( CNTMap );
|
||||
CNTMap = NULL;
|
||||
}
|
||||
|
||||
CNTMap = (u8*)NANDLoadFile( "/shared1/content.map", CNTSize );
|
||||
|
||||
if( CNTMap == NULL )
|
||||
return ES_FATAL;
|
||||
|
||||
*CNTMapDirty = 0;
|
||||
}
|
||||
|
||||
u32 ID=0;
|
||||
for( ID=0; ID < *CNTSize/0x1C; ++ID )
|
||||
{
|
||||
if( memcmp( CNTMap+ID*0x1C+8, ContentHash, 0x14 ) == 0 )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
Returns the content id for the supplied hash if found
|
||||
|
||||
returns:
|
||||
0 < on error
|
||||
id on found
|
||||
*/
|
||||
s32 GetSharedContentID( void *ContentHash )
|
||||
{
|
||||
if( *CNTMapDirty )
|
||||
{
|
||||
dbgprintf("ES:Loading content.map...\n");
|
||||
|
||||
if( CNTMap != NULL )
|
||||
{
|
||||
free( CNTMap );
|
||||
CNTMap = (u8*)NULL;
|
||||
}
|
||||
|
||||
CNTMap = (u8*)NANDLoadFile( "/shared1/content.map", CNTSize );
|
||||
|
||||
if( CNTMap == NULL )
|
||||
return ES_FATAL;
|
||||
|
||||
*CNTMapDirty = 0;
|
||||
}
|
||||
|
||||
u32 ID=0;
|
||||
for( ID=0; ID < *CNTSize/0x1C; ++ID )
|
||||
{
|
||||
if( memcmp( CNTMap+ID*0x1C+8, ContentHash, 0x14 ) == 0 )
|
||||
return ID;
|
||||
}
|
||||
|
||||
return ES_FATAL;
|
||||
}
|
||||
|
||||
void GetTicketView( u8 *Ticket, u8 *oTicketView )
|
||||
{
|
||||
u8 *TikView = (u8*)malloca( 0xD8, 32 );
|
||||
|
||||
memset32( TikView, 0, 0xD8 );
|
||||
|
||||
TikView[0] = Ticket[0x1BC];
|
||||
|
||||
*(u64*)(TikView+0x04) = *(u64*)(Ticket+0x1D0);
|
||||
*(u32*)(TikView+0x0C) = *(u32*)(Ticket+0x1D8);
|
||||
*(u64*)(TikView+0x10) = *(u64*)(Ticket+0x1DC);
|
||||
*(u16*)(TikView+0x18) = *(u16*)(Ticket+0x1E4);
|
||||
*(u16*)(TikView+0x1A) = *(u16*)(Ticket+0x1E6);
|
||||
*(u32*)(TikView+0x1C) = *(u32*)(Ticket+0x1E8);
|
||||
*(u32*)(TikView+0x20) = *(u32*)(Ticket+0x1EC);
|
||||
*(u8*) (TikView+0x24) = *(u8*) (Ticket+0x1F0);
|
||||
|
||||
memcpy( TikView+0x25, Ticket+0x1F1, 0x30 );
|
||||
|
||||
*(u8*) (TikView+0x55) = *(u8*) (Ticket+0x221);
|
||||
|
||||
memcpy( TikView+0x56, Ticket+0x222, 0x40 );
|
||||
|
||||
u32 i;
|
||||
for( i=0; i < 7; ++i )
|
||||
{
|
||||
*(u32*)(i*8 + TikView + 0x98) = *(u32*)(i*8 + Ticket + 0x264);
|
||||
*(u32*)(i*8 + TikView + 0x9C) = *(u32*)(i*8 + Ticket + 0x268);
|
||||
}
|
||||
|
||||
memcpy( oTicketView, TikView, 0xD8 );
|
||||
|
||||
free( TikView );
|
||||
|
||||
return;
|
||||
}
|
148
kernel/ES.h
Normal file
148
kernel/ES.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifndef __ES_H__
|
||||
#define __ES_H__
|
||||
|
||||
#include "syscalls.h"
|
||||
#include "ipc.h"
|
||||
#include "global.h"
|
||||
#include "string.h"
|
||||
#include "DI.h"
|
||||
#include "Config.h"
|
||||
#include "ff.h"
|
||||
#include "NAND.h"
|
||||
|
||||
#define TICKET_SIZE 0x2A4
|
||||
|
||||
enum ESStatus
|
||||
{
|
||||
ES_SUCCESS = 0,
|
||||
ES_NFOUND = -106,
|
||||
ES_FATAL = -1017,
|
||||
ES_EHASH = -1022,
|
||||
ES_ETIKTMD = -1029,
|
||||
ES_EFAIL = -4100,
|
||||
};
|
||||
|
||||
|
||||
#define SHA_INIT 0
|
||||
#define SHA_UPDATE 1
|
||||
#define SHA_FINISH 2
|
||||
|
||||
enum ESModuleHandles
|
||||
{
|
||||
ES_FD = 0,
|
||||
SD_FD = 155,
|
||||
};
|
||||
|
||||
enum ContentType
|
||||
{
|
||||
CONTENT_REQUIRED= (1<< 0), // not sure
|
||||
CONTENT_SHARED = (1<<15),
|
||||
CONTENT_OPTIONAL= (1<<14),
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 ID; // 0 (0x1E4)
|
||||
u16 Index; // 4 (0x1E8)
|
||||
u16 Type; // 6 (0x1EA)
|
||||
u64 Size; // 8 (0x1EC)
|
||||
u8 SHA1[20]; // 12 (0x1F4)
|
||||
} __attribute__((packed)) Content;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 SignatureType; // 0x000
|
||||
u8 Signature[0x100]; // 0x004
|
||||
|
||||
u8 Padding0[0x3C]; // 0x104
|
||||
u8 Issuer[0x40]; // 0x140
|
||||
|
||||
u8 Version; // 0x180
|
||||
u8 CACRLVersion; // 0x181
|
||||
u8 SignerCRLVersion; // 0x182
|
||||
u8 Padding1; // 0x183
|
||||
|
||||
u64 SystemVersion; // 0x184
|
||||
u64 TitleID; // 0x18C
|
||||
u32 TitleType; // 0x194
|
||||
u16 GroupID; // 0x198
|
||||
u8 Reserved[62]; // 0x19A
|
||||
u32 AccessRights; // 0x1D8
|
||||
u16 TitleVersion; // 0x1DC
|
||||
u16 ContentCount; // 0x1DE
|
||||
u16 BootIndex; // 0x1E0
|
||||
u8 Padding3[2]; // 0x1E2
|
||||
|
||||
Content Contents[]; // 0x1E4
|
||||
|
||||
} __attribute__((packed)) TitleMetaData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 SignatureType; // 0x000
|
||||
u8 Signature[0x100]; // 0x004
|
||||
|
||||
u8 Padding[0x3C]; // 0x104
|
||||
s8 SignatureIssuer[0x40]; // 0x140
|
||||
u8 DownloadContent[0x3F]; // 0x180
|
||||
u8 EncryptedTitleKey[0x10];// 0x1BF
|
||||
u8 Unknown; // 0x1CF
|
||||
u64 TicketID; // 0x1D0
|
||||
u32 ConsoleID; // 0x1D8
|
||||
u64 TitleID; // 0x1DC
|
||||
u16 UnknownA; // 0x1E4
|
||||
u16 BoughtContents; // 0x1E6
|
||||
u8 UknownB[0x08]; // 0x1E9
|
||||
u8 CommonKeyIndex; // 0x1F1
|
||||
u8 UnknownC[0x30]; // 0x1F2
|
||||
u8 UnknownD[0x20]; // 0x222
|
||||
u16 PaddingA; // 0x242
|
||||
u32 TimeLimitEnabled; // 0x248
|
||||
u32 TimeLimit; // 0x24C
|
||||
|
||||
} __attribute__((packed)) Ticket;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 Unknown; // 0x000
|
||||
u8 Padding[3]; // 0x001
|
||||
u64 TicketID; // 0x004
|
||||
u32 ConsoleID; // 0x00C
|
||||
u64 TitleID; // 0x010
|
||||
u16 UnknownA; // 0x
|
||||
u16 BoughtContents; // 0x
|
||||
u8 UknownB[0x08]; // 0x
|
||||
u8 CommonKeyIndex; // 0x
|
||||
u8 UnknownC[0x30]; // 0x
|
||||
u8 UnknownD[0x20]; // 0x
|
||||
u16 PaddingA; // 0x
|
||||
u32 TimeLimitEnabled; // 0x
|
||||
u32 TimeLimit; // 0x
|
||||
|
||||
} __attribute__((packed)) TicketView;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 TitleID; //
|
||||
u16 Padding; //
|
||||
u16 GroupID; //
|
||||
|
||||
} __attribute__((packed)) UIDSYS;
|
||||
|
||||
u32 ES_Init( u8 *MessageHeap );
|
||||
|
||||
s32 LaunchTitle( u64 TitleID );
|
||||
s32 ES_BootSystem( void );
|
||||
s32 LoadModules( u32 IOSVersion );
|
||||
|
||||
s32 GetSharedContentID( void *ContentHash );
|
||||
s32 GetUID( u64 *TitleID, u16 *UID );
|
||||
u64 GetTitleID( void );
|
||||
void iCleanUpTikTMD( void );
|
||||
|
||||
void GetTicketView( u8 *Ticket, u8 *oTicketView );
|
||||
s32 ESP_OpenContent( u64 TitleID, u32 ContentID );
|
||||
s32 ESP_LaunchTitle( u64 *TitleID, u8 *TikView );
|
||||
|
||||
#endif
|
694
kernel/EXI.c
Normal file
694
kernel/EXI.c
Normal file
@@ -0,0 +1,694 @@
|
||||
/*
|
||||
|
||||
Nintendont (Kernel) - Playing Gamecubes in Wii mode on a Wii U
|
||||
|
||||
Copyright (C) 2013 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#include "global.h"
|
||||
#include "EXI.h"
|
||||
#include "ff.h"
|
||||
#include "common.h"
|
||||
#include "vsprintf.h"
|
||||
#include "alloc.h"
|
||||
#include "Patch.h"
|
||||
#include "syscalls.h"
|
||||
#include "Config.h"
|
||||
#include "debug.h"
|
||||
|
||||
//#define DEBUG_EXI 1
|
||||
//#define DEBUG_SRAM 1
|
||||
|
||||
extern u8 SRAM[64];
|
||||
extern u32 Region;
|
||||
|
||||
u32 Device=0;
|
||||
u32 SRAMWriteCount=0;
|
||||
static u32 EXICommand = 0;
|
||||
static u32 BlockOff= 0;
|
||||
static u32 BlockOffLow = 0xFFFFFFFF;
|
||||
u8 *MCard = (u8 *)(0x11000000);
|
||||
u32 CARDWriteCount = 0;
|
||||
u32 IPLReadOffset;
|
||||
FIL MemCard;
|
||||
bool SkipHandlerWait = false;
|
||||
|
||||
static TCHAR MemCardName[9];
|
||||
void EXIInit( void )
|
||||
{
|
||||
dbgprintf("EXIInit Start\n");
|
||||
u32 i, wrote, ret;
|
||||
|
||||
write32( 0x0D80600C, 0 );
|
||||
write32( 0x0D806010, 0 );
|
||||
|
||||
if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) )
|
||||
{
|
||||
f_chdir("/saves");
|
||||
u32 GameID = ConfigGetGameID();
|
||||
memset32(MemCardName, 0, 9);
|
||||
memcpy(MemCardName, &GameID, 4);
|
||||
memcpy(MemCardName+4, ".raw", 4);
|
||||
sync_after_write(MemCardName, 0x20);
|
||||
|
||||
dbgprintf("Trying to open %s\n", MemCardName);
|
||||
ret = f_open( &MemCard, MemCardName, FA_READ );
|
||||
if( ret != FR_OK || MemCard.fsize == 0 )
|
||||
{
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: Failed to open %s:%u\n", MemCardName, ret );
|
||||
#endif
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: Loading memory card...");
|
||||
#endif
|
||||
|
||||
f_lseek( &MemCard, 0 );
|
||||
f_read( &MemCard, MCard, NIN_RAW_MEMCARD_SIZE, &wrote );
|
||||
f_close( &MemCard );
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("done\n");
|
||||
#endif
|
||||
sync_after_write( MCard, NIN_RAW_MEMCARD_SIZE );
|
||||
}
|
||||
|
||||
GC_SRAM *sram = (GC_SRAM*)SRAM;
|
||||
|
||||
for( i=0; i < 12; ++i )
|
||||
sram->FlashID[0][i] = 0;
|
||||
|
||||
sram->FlashIDChecksum[0] = 0xFF;
|
||||
|
||||
sram->DisplayOffsetH = 0;
|
||||
sram->BootMode &= ~0x40; // Clear PAL60
|
||||
sram->Flags &= ~3; // Clear Videomode
|
||||
sram->Flags &= ~0x80; // Clear Progmode
|
||||
|
||||
sram->Language = ConfigGetLanguage();
|
||||
|
||||
if( ConfigGetVideoMode() & NIN_VID_FORCE )
|
||||
{
|
||||
switch( ConfigGetVideoMode() & NIN_VID_FORCE_MASK )
|
||||
{
|
||||
case NIN_VID_FORCE_NTSC:
|
||||
{
|
||||
Region = 0;
|
||||
} break;
|
||||
case NIN_VID_FORCE_MPAL:
|
||||
case NIN_VID_FORCE_PAL50:
|
||||
case NIN_VID_FORCE_PAL60:
|
||||
{
|
||||
Region = 2;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(Region)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("SRAM:NTSC\n");
|
||||
#endif
|
||||
*(vu32*)0xCC = 0;
|
||||
|
||||
} break;
|
||||
case 2:
|
||||
{
|
||||
#ifdef DEBUG_EXI
|
||||
if( *(vu32*)0xCC == 5 )
|
||||
{
|
||||
dbgprintf("SRAM:PAL60\n");
|
||||
} else {
|
||||
dbgprintf("SRAM:PAL50\n");
|
||||
*(vu32*)0xCC = 1;
|
||||
}
|
||||
#endif
|
||||
sram->Flags |= 1;
|
||||
sram->BootMode |= 0x40;
|
||||
|
||||
} break;
|
||||
}
|
||||
if( ConfigGetVideoMode() & NIN_VID_PROG )
|
||||
sram->Flags |= 0x80;
|
||||
else
|
||||
sram->Flags &= 0x7F;
|
||||
|
||||
SRAM_Checksum( (unsigned short *)SRAM, (unsigned short *)SRAM, (unsigned short *)( ((u8*)SRAM) + 2 ) );
|
||||
|
||||
}
|
||||
|
||||
bool EXICheckCard(void)
|
||||
{
|
||||
if(BlockOffLow != 0xFFFFFFFF)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EXISaveCard(void)
|
||||
{
|
||||
u32 wrote;
|
||||
|
||||
if(BlockOffLow != 0xFFFFFFFF)
|
||||
{
|
||||
//#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: Saving memory card...");
|
||||
//#endif
|
||||
s32 ret = f_open( &MemCard, MemCardName, FA_WRITE );
|
||||
if( ret == FR_OK )
|
||||
{
|
||||
sync_before_read(MCard, NIN_RAW_MEMCARD_SIZE);
|
||||
f_lseek(&MemCard, BlockOffLow);
|
||||
f_write(&MemCard, MCard + BlockOffLow, (NIN_RAW_MEMCARD_SIZE) - BlockOffLow, &wrote);
|
||||
f_close(&MemCard);
|
||||
//#ifdef DEBUG_EXI
|
||||
dbgprintf("Done!\n");
|
||||
}
|
||||
else
|
||||
dbgprintf("Unable to open memory card file!\n");
|
||||
//#endif
|
||||
BlockOffLow = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void EXIShutdown( void )
|
||||
{
|
||||
u32 wrote;
|
||||
|
||||
//#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: Saving memory card...");
|
||||
//#endif
|
||||
|
||||
sync_before_read( MCard, NIN_RAW_MEMCARD_SIZE );
|
||||
s32 ret = f_open( &MemCard, MemCardName, FA_WRITE );
|
||||
if( ret == FR_OK )
|
||||
{
|
||||
f_lseek( &MemCard, 0 );
|
||||
f_write( &MemCard, MCard, NIN_RAW_MEMCARD_SIZE, &wrote );
|
||||
f_close( &MemCard );
|
||||
}
|
||||
else
|
||||
dbgprintf("Unable to open memory card file!\n");
|
||||
//#ifdef DEBUG_EXI
|
||||
dbgprintf("Done!\n");
|
||||
//#endif
|
||||
}
|
||||
u32 EXIDeviceMemoryCard( u8 *Data, u32 Length, u32 Mode )
|
||||
{
|
||||
u32 EXIOK = 1;
|
||||
//u32 read, wrote;
|
||||
|
||||
if( Mode == 1 ) // Write
|
||||
{
|
||||
switch( Length )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if( EXICommand == MEM_BLOCK_READ || EXICommand == MEM_BLOCK_WRITE )
|
||||
break;
|
||||
|
||||
switch( (u32)Data >> 24 )
|
||||
{
|
||||
case 0x00:
|
||||
{
|
||||
EXICommand = MEM_READ_ID_NINTENDO;
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDGetDeviceIDNintendo()\n");
|
||||
#endif
|
||||
} break;
|
||||
#ifdef DEBUG_EXI
|
||||
case 0x89:
|
||||
{
|
||||
dbgprintf("EXI: CARDClearStatus()\n");
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case 2:
|
||||
{
|
||||
switch( (u32)Data >> 16 )
|
||||
{
|
||||
case 0x0000:
|
||||
{
|
||||
EXICommand = MEM_READ_ID;
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDGetDeviceID()\n");
|
||||
#endif
|
||||
} break;
|
||||
case 0x8300: //
|
||||
{
|
||||
EXICommand = MEM_READ_STATUS;
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDReadStatus()\n");
|
||||
#endif
|
||||
} break;
|
||||
#ifdef DEBUG_EXI
|
||||
case 0x8101:
|
||||
{
|
||||
dbgprintf("EXI: CARDIRQEnable()\n");
|
||||
} break;
|
||||
case 0x8100:
|
||||
{
|
||||
dbgprintf("EXI: CARDIRQDisable()\n");
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case 3:
|
||||
{
|
||||
switch( (u32)Data >> 24 )
|
||||
{
|
||||
case 0xF1:
|
||||
{
|
||||
BlockOff = (((u32)Data>>16)&0xFF) << 17;
|
||||
BlockOff|= (((u32)Data>> 8)&0xFF) << 9;
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDErasePage(%08X)\n", BlockOff );
|
||||
#endif
|
||||
EXICommand = MEM_BLOCK_ERASE;
|
||||
CARDWriteCount = 0;
|
||||
write32( 0x10, 2 ); // EXI IRQ
|
||||
EXIOK = 2;
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
case 4:
|
||||
{
|
||||
if( EXICommand == MEM_BLOCK_READ || EXICommand == MEM_BLOCK_WRITE )
|
||||
break;
|
||||
|
||||
switch( (u32)Data >> 24 )
|
||||
{
|
||||
case 0xF1:
|
||||
{
|
||||
BlockOff = (((u32)Data>>16)&0xFF) << 17;
|
||||
BlockOff|= (((u32)Data>> 8)&0xFF) << 9;
|
||||
BlockOff|= (((u32)Data&0xFF) & 3 ) << 7;
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDErasePage(%08X)\n", BlockOff );
|
||||
#endif
|
||||
EXICommand = MEM_BLOCK_ERASE;
|
||||
CARDWriteCount = 0;
|
||||
write32( 0x10, 2 ); // EXI IRQ
|
||||
EXIOK = 2;
|
||||
} break;
|
||||
case 0xF2:
|
||||
{
|
||||
BlockOff = (((u32)Data>>16)&0xFF) << 17;
|
||||
BlockOff|= (((u32)Data>> 8)&0xFF) << 9;
|
||||
BlockOff|= (((u32)Data&0xFF) & 3 ) << 7;
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDWritePage(%08X)\n", BlockOff );
|
||||
#endif
|
||||
if(BlockOff < BlockOffLow)
|
||||
BlockOffLow = BlockOff;
|
||||
|
||||
EXICommand = MEM_BLOCK_WRITE;
|
||||
} break;
|
||||
case 0x52:
|
||||
{
|
||||
BlockOff = (((u32)Data>>16)&0xFF) << 17;
|
||||
BlockOff|= (((u32)Data>> 8)&0xFF) << 9;
|
||||
BlockOff|= (((u32)Data&0xFF) & 3 ) << 7;
|
||||
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDReadPage(%08X)\n", BlockOff );
|
||||
#endif
|
||||
|
||||
EXICommand = MEM_BLOCK_READ;
|
||||
} break;
|
||||
#ifdef DEBUG_EXI
|
||||
default:
|
||||
{
|
||||
dbgprintf("EXI: Unknown:%08x Line:%u\n", (u32)Data, __LINE__ );
|
||||
// Shutdown();
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
switch( EXICommand )
|
||||
{
|
||||
case MEM_BLOCK_WRITE:
|
||||
{
|
||||
sync_before_read( Data, Length );
|
||||
|
||||
memcpy( MCard+BlockOff, Data, Length );
|
||||
|
||||
sync_after_write( MCard+BlockOff, Length );
|
||||
|
||||
write32( 0x10, 10 ); // TC(8) & EXI(2) IRQ
|
||||
EXIOK = 2;
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
} else { // Read
|
||||
|
||||
switch( EXICommand )
|
||||
{
|
||||
case MEM_READ_ID_NINTENDO:
|
||||
case MEM_READ_ID:
|
||||
{
|
||||
if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) )
|
||||
{
|
||||
write32( 0x0D806010, NIN_MEMCARD_BLOCKS );
|
||||
} else {
|
||||
write32( 0x0D806010, 0x00000000 ); //no memory card
|
||||
}
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDReadID(%X)\n", read32(0x0D806010) );
|
||||
#endif
|
||||
} break;
|
||||
case MEM_READ_STATUS:
|
||||
{
|
||||
write32( 0x0D806010, 0x41 ); // Unlocked(0x40) and Ready(0x01)
|
||||
#ifdef DEBUG_EXI
|
||||
dbgprintf("EXI: CARDReadStatus(%X)\n", read32(0x0D806010) );
|
||||
#endif
|
||||
} break;
|
||||
case MEM_BLOCK_READ:
|
||||
{
|
||||
// f_lseek( &MemCard, BlockOff );
|
||||
// f_read( &MemCard, Data, Length, &read );
|
||||
sync_before_read( MCard+BlockOff, Length );
|
||||
|
||||
memcpy( Data, MCard+BlockOff, Length );
|
||||
|
||||
sync_after_write( Data, Length );
|
||||
|
||||
write32( 0x10, 8 ); // TC IRQ
|
||||
|
||||
EXIOK = 2;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
//dbgprintf("%08x %08x %08x %08x\n", (u32)Data >> 16, Mode, Length, EXICommand);
|
||||
write32( 0x0D80600C, 0 ); //exit EXIDMA / EXIImm
|
||||
write32(0x12010000,1);
|
||||
sync_after_write((void*)0x12010000,0x20);
|
||||
if( EXIOK == 2 )
|
||||
{
|
||||
write32( 0x14, 0x10 ); // EXI(TC) IRQ
|
||||
sync_after_write( 0, 0x20 );
|
||||
wait_for_ppc(1);
|
||||
if(SkipHandlerWait == true)
|
||||
write32( HW_IPC_ARMCTRL, (1<<0) | (1<<4) ); //throw irq
|
||||
else
|
||||
{
|
||||
while(read32(0x12010000) == 1)
|
||||
{
|
||||
write32( HW_IPC_ARMCTRL, (1<<0) | (1<<4) ); //throw irq
|
||||
sync_before_read((void*)0x12010000, 0x20);
|
||||
}
|
||||
}
|
||||
/*write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) );
|
||||
write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) );
|
||||
set32( HW_IPC_ARMCTRL, (1<<2) );*/
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
u32 EXIDevice_ROM_RTC_SRAM_UART( u8 *Data, u32 Length, u32 Mode )
|
||||
{
|
||||
u32 read;
|
||||
|
||||
if( Mode == 1 ) // Write
|
||||
{
|
||||
switch( Length )
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
if( EXICommand == SRAM_WRITE )
|
||||
{
|
||||
*(u32*)(SRAM+SRAMWriteCount) = (u32)Data;
|
||||
|
||||
SRAMWriteCount += Length;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if( (u32)Data == 0x20000100 )
|
||||
{
|
||||
EXICommand = SRAM_READ;
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: SRAMRead()\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if( (u32)Data == 0xA0000100 || (u32)Data == 0xA0000600 )
|
||||
{
|
||||
EXICommand = SRAM_WRITE;
|
||||
SRAMWriteCount = 0;
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: SRAMWrite()\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if( ((u32)Data >> 6 ) >= 0x1FCF00 )
|
||||
{
|
||||
EXICommand = IPL_READ_FONT_ANSI;
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: IPLReadFont()\n");
|
||||
#endif
|
||||
IPLReadOffset = (u32)Data >> 6;
|
||||
break;
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
switch( EXICommand )
|
||||
{
|
||||
case IPL_READ_FONT_ANSI:
|
||||
{
|
||||
FIL ipl;
|
||||
if( f_open( &ipl, "/ipl.bin", FA_OPEN_EXISTING|FA_READ ) == FR_OK )
|
||||
{
|
||||
f_lseek( &ipl, IPLReadOffset );
|
||||
f_read( &ipl, Data, Length, &read );
|
||||
f_close( &ipl );
|
||||
|
||||
sync_after_write( Data, Length );
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: IPLRead( %p, %08X, %u)\n", Data, IPLReadOffset, Length );
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case SRAM_READ:
|
||||
{
|
||||
memcpy( Data, SRAM, Length );
|
||||
|
||||
sync_after_write( Data, Length );
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: SRAMRead(%p,%u)\n", Data, Length );
|
||||
#endif
|
||||
} break;
|
||||
#ifdef DEBUG_SRAM
|
||||
default:
|
||||
{
|
||||
dbgprintf("EXI: Unknown:%08x Line:%u\n", (u32)Data, __LINE__ );
|
||||
Shutdown();
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
write32( 0x0D80600C, 0 );
|
||||
|
||||
return 1;
|
||||
}
|
||||
u32 EXIDeviceSP1( u8 *Data, u32 Length, u32 Mode )
|
||||
{
|
||||
if( Mode == 1 ) // Write
|
||||
{
|
||||
switch( Length )
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
switch( (u32)Data >>16 )
|
||||
{
|
||||
case 0x0000:
|
||||
{
|
||||
EXICommand = MEM_READ_ID;
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
} else {
|
||||
switch(EXICommand)
|
||||
{
|
||||
case MEM_READ_ID:
|
||||
{
|
||||
write32( 0x0D806010, 0 );
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
write32( 0x0D80600C, 0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
void EXIUpdateRegistersNEW( void )
|
||||
{
|
||||
//u32 chn, dev, frq, ret, data, len, mode;
|
||||
u32 chn, dev, ret, data, len, mode;
|
||||
u8 *ptr;
|
||||
|
||||
u32 command = read32(0x0D80600C);
|
||||
|
||||
if( command & 0xFF000000 )
|
||||
{
|
||||
switch( command >> 24 )
|
||||
{
|
||||
case 0x10: // EXISelect
|
||||
{
|
||||
chn = command & 0xFF;
|
||||
dev = (command>>8) & 0xFF;
|
||||
//frq = (command>>16) & 0xFF;
|
||||
|
||||
// dbgprintf("EXISelect( %u, %u, %u )\n", chn, dev, frq );
|
||||
ret = 1;
|
||||
|
||||
switch( chn )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
switch( dev )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Device = EXI_DEV_MEMCARD_A;
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
Device = EXI_DEV_MASK_ROM_RTC_SRAM_UART;
|
||||
} break;
|
||||
case 2:
|
||||
{
|
||||
Device = EXI_DEV_SP1;
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
Device = EXI_DEV_MEMCARD_B;
|
||||
ret = 0;
|
||||
} break;
|
||||
case 2:
|
||||
{
|
||||
Device = EXI_DEV_AD16;
|
||||
ret = 0;
|
||||
} break;
|
||||
}
|
||||
|
||||
EXICommand = 0;
|
||||
|
||||
write32( 0x0D806010, ret );
|
||||
write32( 0x0D80600C, 0 );
|
||||
|
||||
} break;
|
||||
case 0x11: // EXI_Imm( s32 nChn, void *pData, u32 nLen, u32 nMode, EXICallback tc_cb );
|
||||
{
|
||||
chn = (command >> 20) & 0xF;
|
||||
data= read32(0x0D806010);
|
||||
len = command& 0xFFFF;
|
||||
mode= (command >> 16) & 0xF;
|
||||
|
||||
if( len > 4 )
|
||||
{
|
||||
data = P2C(data);
|
||||
}
|
||||
|
||||
// dbgprintf("EXIImm( %u, %p, %u, %u, Dev:%u EC:%u )\n", chn, data, len, mode, Device, EXICommand );
|
||||
switch( Device )
|
||||
{
|
||||
case EXI_DEV_MEMCARD_A:
|
||||
{
|
||||
EXIDeviceMemoryCard( (u8*)data, len, mode );
|
||||
} break;
|
||||
case EXI_DEV_MASK_ROM_RTC_SRAM_UART:
|
||||
{
|
||||
EXIDevice_ROM_RTC_SRAM_UART( (u8*)data, len, mode );
|
||||
} break;
|
||||
case EXI_DEV_SP1:
|
||||
{
|
||||
EXIDeviceSP1( (u8*)data, len, mode );
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: EXIImm: Unhandled device:%u\n", Device );
|
||||
#endif
|
||||
} break;
|
||||
}
|
||||
|
||||
} break;
|
||||
case 0x12: // EXIDMA
|
||||
{
|
||||
chn = (command >> 20) & 0xF;
|
||||
ptr= (u8*)P2C(read32(0x0D806010));
|
||||
len = command& 0xFFFF;
|
||||
mode= (command >> 16) & 0xF;
|
||||
|
||||
// dbgprintf("EXIDMA( %u, %p, %u, %u )\n", chn, ptr, len, mode );
|
||||
switch( Device )
|
||||
{
|
||||
case EXI_DEV_MEMCARD_A:
|
||||
{
|
||||
EXIDeviceMemoryCard( ptr, len, mode );
|
||||
} break;
|
||||
case EXI_DEV_MASK_ROM_RTC_SRAM_UART:
|
||||
{
|
||||
EXIDevice_ROM_RTC_SRAM_UART( ptr, len, mode );
|
||||
} break;
|
||||
case EXI_DEV_SP1:
|
||||
{
|
||||
#ifdef DEBUG_SRAM
|
||||
hexdump( ptr, len );
|
||||
#endif
|
||||
EXIDeviceSP1( ptr, len, mode );
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
#ifdef DEBUG_SRAM
|
||||
dbgprintf("EXI: EXIDMA: Unhandled device:%u\n", Device );
|
||||
#endif
|
||||
} break;
|
||||
}
|
||||
|
||||
EXICommand = 0;
|
||||
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
68
kernel/EXI.h
Normal file
68
kernel/EXI.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef __EXI_H__
|
||||
#define __EXI_H__
|
||||
#include "global.h"
|
||||
|
||||
#ifdef EXIPATCH
|
||||
|
||||
enum EXIDevice
|
||||
{
|
||||
EXI_DEV_NONE,
|
||||
EXI_DEV_MEMCARD_A,
|
||||
EXI_DEV_MEMCARD_B,
|
||||
EXI_DEV_MASK_ROM_RTC_SRAM_UART,
|
||||
EXI_DEV_AD16,
|
||||
EXI_DEV_SP1,
|
||||
EXI_DEV_ETH,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BBA_RECV_SIZE = 0x800,
|
||||
BBA_MEM_SIZE = 0x1000,
|
||||
|
||||
CB_OFFSET = 0x100,
|
||||
CB_SIZE = (BBA_MEM_SIZE - CB_OFFSET),
|
||||
SIZEOF_ETH_HEADER = 0xe,
|
||||
SIZEOF_RECV_DESCRIPTOR = 4,
|
||||
|
||||
EXI_DEVTYPE_ETHER = 0x04020200,
|
||||
};
|
||||
|
||||
enum EXICommands {
|
||||
MEM_READ_ID = 1,
|
||||
MEM_READ_ID_NINTENDO,
|
||||
MEM_READ_STATUS,
|
||||
MEM_BLOCK_READ,
|
||||
MEM_BLOCK_WRITE,
|
||||
MEM_BLOCK_ERASE,
|
||||
MEM_FORMAT,
|
||||
|
||||
SRAM_READ,
|
||||
SRAM_WRITE,
|
||||
|
||||
IPL_READ_FONT_ANSI,
|
||||
};
|
||||
|
||||
#define MC_STATUS_BUSY 0x80
|
||||
#define MC_STATUS_UNLOCKED 0x40
|
||||
#define MC_STATUS_SLEEP 0x20
|
||||
#define MC_STATUS_ERASEERROR 0x10
|
||||
#define MC_STATUS_PROGRAMEERROR 0x08
|
||||
#define MC_STATUS_READY 0x01
|
||||
#define SIZE_TO_Mb (1024 * 8 * 16)
|
||||
#define MC_HDR_SIZE 0xA000
|
||||
|
||||
|
||||
#define EXI_READ 0
|
||||
#define EXI_WRITE 1
|
||||
#define EXI_READWRITE 2
|
||||
|
||||
void EXIInit();
|
||||
void EXIUpdateRegistersNEW( void );
|
||||
void EXIShutdown( void );
|
||||
void EXISaveCard(void);
|
||||
bool EXICheckCard(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
316
kernel/FST.c
Normal file
316
kernel/FST.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
|
||||
Nintendont (Kernel) - Playing Gamecubes in Wii mode on a Wii U
|
||||
|
||||
Copyright (C) 2013 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#include "FST.h"
|
||||
#include "ff.h"
|
||||
#include "common.h"
|
||||
#include "alloc.h"
|
||||
#include "vsprintf.h"
|
||||
|
||||
#ifndef DEBUG_DI
|
||||
#define dbgprintf(...)
|
||||
#else
|
||||
extern int dbgprintf( const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
static u8 *FSTable ALIGNED(32);
|
||||
u32 ApploaderSize=0;
|
||||
u32 dolOffset=0;
|
||||
u32 FSTMode = 0;
|
||||
u32 FSTableSize=0;
|
||||
u32 FSTableOffset=0;
|
||||
|
||||
u32 FCEntry=0;
|
||||
FileCache *FC;
|
||||
u32 FCState[FILECACHE_MAX];
|
||||
|
||||
extern u32 Region;
|
||||
|
||||
u32 FSTInit( char *GamePath )
|
||||
{
|
||||
char Path[256];
|
||||
FIL fd;
|
||||
u32 read;
|
||||
|
||||
_sprintf( Path, "%ssys/boot.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
|
||||
u8 *rbuf = (u8*)malloc( 0x100 );
|
||||
|
||||
f_lseek( &fd, 0 );
|
||||
f_read( &fd, rbuf, 0x100, &read );
|
||||
|
||||
dbgprintf("DIP:Loading game %.6s: %s\n", rbuf, (char *)(rbuf+0x20));
|
||||
|
||||
//Read DOL/FST offset/sizes for later usage
|
||||
f_lseek( &fd, 0x0420 );
|
||||
f_read( &fd, rbuf, 0x20, &read );
|
||||
|
||||
dolOffset = *(u32*)(rbuf);
|
||||
FSTableOffset = *(u32*)(rbuf+4);
|
||||
FSTableSize = *(u32*)(rbuf+8);
|
||||
|
||||
free( rbuf );
|
||||
|
||||
dbgprintf( "DIP:FSTableOffset:%08X\n", FSTableOffset );
|
||||
dbgprintf( "DIP:FSTableSize: %08X\n", FSTableSize );
|
||||
dbgprintf( "DIP:DolOffset: %08X\n", dolOffset );
|
||||
|
||||
FSTMode = 1;
|
||||
|
||||
FC = (FileCache*)malloc( sizeof(FileCache) * FILECACHE_MAX );
|
||||
|
||||
f_close( &fd );
|
||||
}
|
||||
|
||||
//Init cache
|
||||
u32 count = 0;
|
||||
for( count=0; count < FILECACHE_MAX; ++count )
|
||||
{
|
||||
FCState[count] = 0xdeadbeef;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
void FSTRead( char *GamePath, char *Buffer, u32 Length, u32 Offset )
|
||||
{
|
||||
char Path[256];
|
||||
FIL fd;
|
||||
u32 read;
|
||||
int i,j;
|
||||
|
||||
if( Offset >= FSTableOffset+FSTableSize ) {
|
||||
|
||||
//Get FSTTable offset from low memory, must be set by apploader
|
||||
if( FSTable == NULL )
|
||||
{
|
||||
FSTable = (u8*)((*(vu32*)0x38) & 0x7FFFFFFF);
|
||||
//dbgprintf("DIP:FSTOffset: %08X\n", (u32)FSTable );
|
||||
}
|
||||
|
||||
//try cache first!
|
||||
for( i=0; i < FILECACHE_MAX; ++i )
|
||||
{
|
||||
if( FCState[i] == 0xdeadbeef )
|
||||
continue;
|
||||
|
||||
if( Offset >= FC[i].Offset )
|
||||
{
|
||||
u64 nOffset = Offset - FC[i].Offset;
|
||||
if( nOffset < FC[i].Size )
|
||||
{
|
||||
//dbgprintf("DIP:[Cache:%02d][%08X:%05X]\n", i, (u32)(nOffset>>2), Length );
|
||||
f_lseek( &(FC[i].File), nOffset );
|
||||
f_read( &(FC[i].File), Buffer, ((Length)+31)&(~31), &read );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//The fun part!
|
||||
|
||||
u32 Entries = *(u32*)(FSTable+0x08);
|
||||
char *NameOff = (char*)(FSTable + Entries * 0x0C);
|
||||
FEntry *fe = (FEntry*)(FSTable);
|
||||
|
||||
u32 Entry[16];
|
||||
u32 LEntry[16];
|
||||
u32 level=0;
|
||||
|
||||
for( i=1; i < Entries; ++i )
|
||||
{
|
||||
if( level )
|
||||
{
|
||||
while( LEntry[level-1] == i )
|
||||
{
|
||||
//printf("[%03X]leaving :\"%s\" Level:%d\n", i, buffer + NameOff + swap24( fe[Entry[level-1]].NameOffset ), level );
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
if( fe[i].Type )
|
||||
{
|
||||
//Skip empty folders
|
||||
if( fe[i].NextOffset == i+1 )
|
||||
continue;
|
||||
|
||||
//printf("[%03X]Entering:\"%s\" Level:%d leave:%04X\n", i, buffer + NameOff + swap24( fe[i].NameOffset ), level, swap32( fe[i].NextOffset ) );
|
||||
Entry[level] = i;
|
||||
LEntry[level++] = fe[i].NextOffset;
|
||||
if( level > 15 ) // something is wrong!
|
||||
break;
|
||||
} else {
|
||||
|
||||
if( Offset >= fe[i].FileOffset )
|
||||
{
|
||||
u32 nOffset = (Offset - fe[i].FileOffset);
|
||||
if( nOffset < fe[i].FileLength )
|
||||
{
|
||||
// dbgprintf("DIP:Offset:%08X FOffset:%08X Dif:%08X Flen:%08X nOffset:%08X\n", Offset, fe[i].FileOffset, Offset-fe[i].FileOffset, fe[i].FileLength, nOffset );
|
||||
|
||||
//Do not remove!
|
||||
memset32( Path, 0, 256 );
|
||||
_sprintf( Path, "%sroot/", GamePath );
|
||||
|
||||
for( j=0; j<level; ++j )
|
||||
{
|
||||
if( j )
|
||||
Path[strlen(Path)] = '/';
|
||||
memcpy( Path+strlen(Path), NameOff + fe[Entry[j]].NameOffset, strlen(NameOff + fe[Entry[j]].NameOffset ) );
|
||||
}
|
||||
if( level )
|
||||
Path[strlen(Path)] = '/';
|
||||
memcpy( Path+strlen(Path), NameOff + fe[i].NameOffset, strlen(NameOff + fe[i].NameOffset) );
|
||||
|
||||
if( FCEntry >= FILECACHE_MAX )
|
||||
FCEntry = 0;
|
||||
|
||||
if( FCState[FCEntry] != 0xdeadbeef )
|
||||
{
|
||||
f_close( &(FC[FCEntry].File) );
|
||||
FCState[FCEntry] = 0xdeadbeef;
|
||||
}
|
||||
|
||||
Asciify( Path );
|
||||
|
||||
// dbgprintf("DIP:[%s]\n", Path+strlen(GamePath)+5 );
|
||||
|
||||
f_open( &(FC[FCEntry].File), Path, FA_READ );
|
||||
|
||||
FC[FCEntry].Size = fe[i].FileLength;
|
||||
FC[FCEntry].Offset = fe[i].FileOffset;
|
||||
FCState[FCEntry] = 0x23;
|
||||
|
||||
f_lseek( &(FC[FCEntry].File), nOffset );
|
||||
f_read( &(FC[FCEntry].File), Buffer, Length, &read );
|
||||
|
||||
FCEntry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( Offset >= FSTableOffset ) {
|
||||
|
||||
Offset -= FSTableOffset;
|
||||
|
||||
_sprintf( Path, "%ssys/fst.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[fst.bin] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
f_close( &fd );
|
||||
|
||||
if( FSTable == NULL )
|
||||
{
|
||||
FSTable = (u8*)Buffer;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ( Offset >= dolOffset ) {
|
||||
|
||||
Offset -= dolOffset;
|
||||
|
||||
_sprintf( Path, "%ssys/main.dol", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[main.dol] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ( Offset >= 0x2440 ) {
|
||||
|
||||
Offset -= 0x2440;
|
||||
|
||||
_sprintf( Path, "%ssys/apploader.img", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[apploader.img] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ( Offset >= 0x440 ) {
|
||||
|
||||
Offset -= 0x440;
|
||||
|
||||
_sprintf( Path, "%ssys/bi2.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[bi2.bin] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
|
||||
f_close( &fd );
|
||||
|
||||
Region = *(vu32*)(Buffer+0x18);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
_sprintf( Path, "%ssys/boot.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[boot.bin] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
46
kernel/FST.h
Normal file
46
kernel/FST.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef __FST_H__
|
||||
#define __FST_H__
|
||||
|
||||
#include "global.h"
|
||||
#include "ff.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 Type :8;
|
||||
u32 NameOffset :24;
|
||||
};
|
||||
u32 TypeName;
|
||||
};
|
||||
union
|
||||
{
|
||||
struct // File Entry
|
||||
{
|
||||
u32 FileOffset;
|
||||
u32 FileLength;
|
||||
};
|
||||
struct // Dir Entry
|
||||
{
|
||||
u32 ParentOffset;
|
||||
u32 NextOffset;
|
||||
};
|
||||
u32 entry[2];
|
||||
};
|
||||
} FEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 Offset;
|
||||
u32 Size;
|
||||
FIL File;
|
||||
} FileCache;
|
||||
|
||||
#define FILECACHE_MAX 2
|
||||
|
||||
u32 FSTInit ( char *GamePath );
|
||||
void FSTRead ( char *GamePath, char *Buffer, u32 Length, u32 Offset );
|
||||
|
||||
#endif
|
48
kernel/GCPad.h
Normal file
48
kernel/GCPad.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef __GCPAD_H__
|
||||
#define __GCPAD_H__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool ErrorStatus :1;
|
||||
bool ErrorLatch :1;
|
||||
u32 Reserved :1;
|
||||
bool Start :1;
|
||||
|
||||
bool Y :1;
|
||||
bool X :1;
|
||||
bool B :1;
|
||||
bool A :1;
|
||||
|
||||
u32 AlwaysSet :1;
|
||||
bool R :1;
|
||||
bool L :1;
|
||||
bool Z :1;
|
||||
|
||||
bool Up :1;
|
||||
bool Down :1;
|
||||
bool Right :1;
|
||||
bool Left :1;
|
||||
|
||||
s16 StickX :8;
|
||||
s16 StickY :8;
|
||||
};
|
||||
u32 Buttons;
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
s16 CStickX;
|
||||
s16 CStickY;
|
||||
s16 LShoulder;
|
||||
s16 RShoulder;
|
||||
};
|
||||
u32 Sticks;
|
||||
};
|
||||
} GCPadStatus;
|
||||
|
||||
#endif
|
442
kernel/HID.c
Normal file
442
kernel/HID.c
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
|
||||
Nintendont (Kernel) - Playing Gamecubes in Wii mode on a Wii U
|
||||
|
||||
Copyright (C) 2013 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#include "HID.h"
|
||||
#include "ff.h"
|
||||
#include "config.h"
|
||||
#include "hidmem.h"
|
||||
|
||||
#ifndef DEBUG_HID
|
||||
#define dbgprintf(...)
|
||||
#else
|
||||
extern int dbgprintf( const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
static u8 ss_led_pattern[8] = {0x0, 0x02, 0x04, 0x08, 0x10, 0x12, 0x14, 0x18};
|
||||
|
||||
s32 HIDHandle = 0;
|
||||
u32 PS3LedSet = 0;
|
||||
u32 DeviceID = 0;
|
||||
u32 bEndpointAddress = 0;
|
||||
u32 wMaxPacketSize = 0;
|
||||
u8 *Packet = (u8*)NULL;
|
||||
|
||||
req_args *req = (req_args *)NULL;
|
||||
|
||||
s32 HIDInit( void )
|
||||
{
|
||||
s32 ret;
|
||||
dbgprintf("HIDInit()\n");
|
||||
HIDHandle = IOS_Open("/dev/usb/hid", 0 );
|
||||
|
||||
char *HIDHeap = (char*)malloca( 0x600, 32 );
|
||||
memset32( HIDHeap, 0, 0x600 );
|
||||
|
||||
req = (req_args*)malloca( sizeof(req_args), 32 );
|
||||
BootStatusError(8, 1);
|
||||
ret = IOS_Ioctl( HIDHandle, /*GetDeviceChange*/0, NULL, 0, HIDHeap, 0x600 );
|
||||
BootStatusError(8, 0);
|
||||
if( ret < 0 )
|
||||
{
|
||||
dbgprintf("HID:GetDeviceChange():%d\n", ret );
|
||||
return -1;
|
||||
}
|
||||
|
||||
DeviceID = *(vu32*)(HIDHeap+4);
|
||||
HIDHandle = HIDHandle;
|
||||
|
||||
dbgprintf("HID:DeviceID:%u\n", DeviceID );
|
||||
dbgprintf("HID:VID:%04X PID:%04X\n", *(vu16*)(HIDHeap+0x10), *(vu16*)(HIDHeap+0x12) );
|
||||
|
||||
u32 Offset = 8;
|
||||
|
||||
u32 DeviceDescLength = *(vu8*)(HIDHeap+Offset);
|
||||
Offset += (DeviceDescLength+3)&(~3);
|
||||
|
||||
u32 ConfigurationLength = *(vu8*)(HIDHeap+Offset);
|
||||
Offset += (ConfigurationLength+3)&(~3);
|
||||
|
||||
u32 InterfaceDescLength = *(vu8*)(HIDHeap+Offset);
|
||||
Offset += (InterfaceDescLength+3)&(~3);
|
||||
|
||||
u32 EndpointDescLengthO = *(vu8*)(HIDHeap+Offset);
|
||||
|
||||
bEndpointAddress = *(vu8*)(HIDHeap+Offset+2);
|
||||
|
||||
if( (bEndpointAddress & 0xF0) != 0x80 )
|
||||
Offset += (EndpointDescLengthO+3)&(~3);
|
||||
|
||||
bEndpointAddress = *(vu8*)(HIDHeap+Offset+2);
|
||||
wMaxPacketSize = *(vu16*)(HIDHeap+Offset+4);
|
||||
|
||||
dbgprintf("HID:bEndpointAddress:%02X\n", bEndpointAddress );
|
||||
dbgprintf("HID:wMaxPacketSize :%u\n", wMaxPacketSize );
|
||||
|
||||
if( *(vu16*)(HIDHeap+0x10) == 0x054c && *(vu16*)(HIDHeap+0x12) == 0x0268 )
|
||||
{
|
||||
dbgprintf("HID:PS3 Dualshock Controller detected\n");
|
||||
|
||||
HIDPS3Init();
|
||||
|
||||
HIDPS3SetRumble( 0, 0, 0, 0 );
|
||||
|
||||
Packet = (u8*)malloca(SS_DATA_LEN, 32);
|
||||
}
|
||||
|
||||
//Load controller config
|
||||
FIL f;
|
||||
u32 read;
|
||||
|
||||
ret = f_open( &f, "/controller.ini", FA_OPEN_EXISTING|FA_READ);
|
||||
if( ret == FR_OK )
|
||||
{
|
||||
char *Data = (char*)malloc( f.fsize );
|
||||
f_read( &f, Data, f.fsize, &read );
|
||||
f_close(&f);
|
||||
|
||||
HID_CTRL->VID = ConfigGetValue( Data, "VID", 0 );
|
||||
HID_CTRL->PID = ConfigGetValue( Data, "PID", 0 );
|
||||
|
||||
if( *(vu16*)(HIDHeap+0x10) != HID_CTRL->VID || *(vu16*)(HIDHeap+0x12) != HID_CTRL->PID )
|
||||
{
|
||||
dbgprintf("HID:Config does not match device VID/PID\n");
|
||||
dbgprintf("HID:Config VID:%04X PID:%04X\n", HID_CTRL->VID, HID_CTRL->PID );
|
||||
|
||||
return -3;
|
||||
}
|
||||
|
||||
HID_CTRL->DPAD = ConfigGetValue( Data, "DPAD", 0 );
|
||||
HID_CTRL->DigitalLR = ConfigGetValue( Data, "DigitalLR", 0 );
|
||||
HID_CTRL->Polltype = ConfigGetValue( Data, "Polltype", 0 );
|
||||
HID_CTRL->MultiIn = ConfigGetValue( Data, "MultiIn", 0 );
|
||||
if( HID_CTRL->MultiIn )
|
||||
{
|
||||
HID_CTRL->MultiInValue= ConfigGetValue( Data, "MultiInValue", 0 );
|
||||
|
||||
dbgprintf("HID:MultIn:%u\n", HID_CTRL->MultiIn );
|
||||
dbgprintf("HID:MultiInValue:%u\n", HID_CTRL->MultiInValue );
|
||||
}
|
||||
|
||||
if( Packet == (u8*)NULL )
|
||||
{
|
||||
if( HID_CTRL->Polltype )
|
||||
{
|
||||
Packet = (u8*)malloca(wMaxPacketSize, 32);
|
||||
} else if( HID_CTRL->Polltype == 0 ) {
|
||||
Packet = (u8*)malloca(128, 32);
|
||||
} else {
|
||||
dbgprintf("HID: %u is an invalid Polltype value\n", HID_CTRL->Polltype );
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
if( HID_CTRL->DPAD > 1 )
|
||||
{
|
||||
dbgprintf("HID: %u is an invalid DPAD value\n", HID_CTRL->DPAD );
|
||||
return -5;
|
||||
}
|
||||
|
||||
HID_CTRL->Power.Offset = ConfigGetValue( Data, "Power", 0 );
|
||||
HID_CTRL->Power.Mask = ConfigGetValue( Data, "Power", 1 );
|
||||
|
||||
HID_CTRL->A.Offset = ConfigGetValue( Data, "A", 0 );
|
||||
HID_CTRL->A.Mask = ConfigGetValue( Data, "A", 1 );
|
||||
|
||||
HID_CTRL->B.Offset = ConfigGetValue( Data, "B", 0 );
|
||||
HID_CTRL->B.Mask = ConfigGetValue( Data, "B", 1 );
|
||||
|
||||
HID_CTRL->X.Offset = ConfigGetValue( Data, "X", 0 );
|
||||
HID_CTRL->X.Mask = ConfigGetValue( Data, "X", 1 );
|
||||
|
||||
HID_CTRL->Y.Offset = ConfigGetValue( Data, "Y", 0 );
|
||||
HID_CTRL->Y.Mask = ConfigGetValue( Data, "Y", 1 );
|
||||
|
||||
HID_CTRL->Z.Offset = ConfigGetValue( Data, "Z", 0 );
|
||||
HID_CTRL->Z.Mask = ConfigGetValue( Data, "Z", 1 );
|
||||
|
||||
HID_CTRL->L.Offset = ConfigGetValue( Data, "L", 0 );
|
||||
HID_CTRL->L.Mask = ConfigGetValue( Data, "L", 1 );
|
||||
|
||||
HID_CTRL->R.Offset = ConfigGetValue( Data, "R", 0 );
|
||||
HID_CTRL->R.Mask = ConfigGetValue( Data, "R", 1 );
|
||||
|
||||
HID_CTRL->S.Offset = ConfigGetValue( Data, "S", 0 );
|
||||
HID_CTRL->S.Mask = ConfigGetValue( Data, "S", 1 );
|
||||
|
||||
|
||||
HID_CTRL->Left.Offset = ConfigGetValue( Data, "Left", 0 );
|
||||
HID_CTRL->Left.Mask = ConfigGetValue( Data, "Left", 1 );
|
||||
|
||||
HID_CTRL->Down.Offset = ConfigGetValue( Data, "Down", 0 );
|
||||
HID_CTRL->Down.Mask = ConfigGetValue( Data, "Down", 1 );
|
||||
|
||||
HID_CTRL->Right.Offset = ConfigGetValue( Data, "Right", 0 );
|
||||
HID_CTRL->Right.Mask = ConfigGetValue( Data, "Right", 1 );
|
||||
|
||||
HID_CTRL->Up.Offset = ConfigGetValue( Data, "Up", 0 );
|
||||
HID_CTRL->Up.Mask = ConfigGetValue( Data, "Up", 1 );
|
||||
|
||||
if( HID_CTRL->DPAD )
|
||||
{
|
||||
HID_CTRL->RightUp.Offset = ConfigGetValue( Data, "RightUp", 0 );
|
||||
HID_CTRL->RightUp.Mask = ConfigGetValue( Data, "RightUp", 1 );
|
||||
|
||||
HID_CTRL->DownRight.Offset = ConfigGetValue( Data, "DownRight", 0 );
|
||||
HID_CTRL->DownRight.Mask = ConfigGetValue( Data, "DownRight", 1 );
|
||||
|
||||
HID_CTRL->DownLeft.Offset = ConfigGetValue( Data, "DownLeft", 0 );
|
||||
HID_CTRL->DownLeft.Mask = ConfigGetValue( Data, "DownLeft", 1 );
|
||||
|
||||
HID_CTRL->UpLeft.Offset = ConfigGetValue( Data, "UpLeft", 0 );
|
||||
HID_CTRL->UpLeft.Mask = ConfigGetValue( Data, "UpLeft", 1 );
|
||||
}
|
||||
|
||||
HID_CTRL->StickX = ConfigGetValue( Data, "StickX", 0 );
|
||||
HID_CTRL->StickY = ConfigGetValue( Data, "StickY", 0 );
|
||||
|
||||
HID_CTRL->CStickX = ConfigGetValue( Data, "CStickX", 0 );
|
||||
HID_CTRL->CStickY = ConfigGetValue( Data, "CStickY", 0 );
|
||||
|
||||
HID_CTRL->LAnalog = ConfigGetValue( Data, "LAnalog", 0 );
|
||||
HID_CTRL->RAnalog = ConfigGetValue( Data, "RAnalog", 0 );
|
||||
|
||||
dbgprintf("HID:Config file for VID:%04X PID:%04X loaded\n", HID_CTRL->VID, HID_CTRL->PID );
|
||||
} else {
|
||||
dbgprintf("HID:Failed to open config file:%u\n", ret );
|
||||
free(HIDHeap);
|
||||
return -2;
|
||||
}
|
||||
memset32(HID_Packet, 0, wMaxPacketSize | SS_DATA_LEN); //just to make sure
|
||||
free(HIDHeap);
|
||||
|
||||
return HIDHandle;
|
||||
}
|
||||
void HIDPS3Init()
|
||||
{
|
||||
memset32( req, 0, sizeof( req_args ) );
|
||||
|
||||
char *buf = (char*)malloca( 0x20, 32 );
|
||||
memset32( buf, 0, 0x20 );
|
||||
|
||||
req->device_no = DeviceID;
|
||||
req->control.bmRequestType = USB_REQTYPE_INTERFACE_GET;
|
||||
req->control.bmRequest = USB_REQ_GETREPORT;
|
||||
req->control.wValue = (USB_REPTYPE_FEATURE<<8) | 0xf2;
|
||||
req->control.wIndex = 0;
|
||||
req->control.wLength = 17;
|
||||
req->data = buf;
|
||||
|
||||
s32 ret = IOS_Ioctl( HIDHandle, /*ControlMessage*/2, req, 32, 0, 0 );
|
||||
if( ret < 0 )
|
||||
{
|
||||
dbgprintf("HID:HIDPS3Init:IOS_Ioctl( %u, %u, %p, %u, %u, %u):%d\n", HIDHandle, 2, req, 32, 0, 0, ret );
|
||||
BootStatusError(-8, -6);
|
||||
mdelay(2000);
|
||||
Shutdown();
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
unsigned char rawData[49] =
|
||||
{
|
||||
0x01, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x27, 0x10, 0x00, 0x32,
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32, 0xFF, 0x27, 0x10, 0x00, 0x32, 0xFF, 0x27, 0x10, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00,
|
||||
} ;
|
||||
|
||||
void HIDPS3SetLED( u8 led )
|
||||
{
|
||||
memset32( req, 0, sizeof( req_args ) );
|
||||
|
||||
char *buf = (char*)malloca( 64, 32 );
|
||||
memset32( buf, 0, 64 );
|
||||
|
||||
memcpy( buf, rawData, 49 );
|
||||
|
||||
buf[10] = ss_led_pattern[led];
|
||||
|
||||
req->device_no = DeviceID;
|
||||
req->interrupt.dLength = 49;
|
||||
req->interrupt.endpoint = 0x02;
|
||||
req->data = buf;
|
||||
|
||||
s32 ret = IOS_Ioctl( HIDHandle, /*InterruptMessageIN*/4, req, 32, 0, 0 );
|
||||
if( ret < 0 )
|
||||
dbgprintf("ES:IOS_Ioctl():%d\n", ret );
|
||||
|
||||
free(buf);
|
||||
}
|
||||
void HIDPS3SetRumble( u8 duration_right, u8 power_right, u8 duration_left, u8 power_left)
|
||||
{
|
||||
memset32( req, 0, sizeof( req_args ) );
|
||||
|
||||
char *buf = (char*)malloca( 64, 32 );
|
||||
memset32( buf, 0, 64 );
|
||||
|
||||
memcpy( buf, rawData, 49 );
|
||||
|
||||
buf[3] = power_left;
|
||||
buf[5] = power_right;
|
||||
|
||||
req->device_no = DeviceID;
|
||||
req->interrupt.dLength = 49;
|
||||
req->interrupt.endpoint = 0x02;
|
||||
req->data = buf;
|
||||
|
||||
|
||||
s32 ret = IOS_Ioctl( HIDHandle, /*InterruptMessageIN*/4, req, 32, 0, 0 );
|
||||
if( ret < 0 )
|
||||
dbgprintf("ES:IOS_Ioctl():%d\n", ret );
|
||||
}
|
||||
|
||||
u32 HIDRumbleLast = 0;
|
||||
void HIDPS3Read()
|
||||
{
|
||||
s32 ret;
|
||||
memset32( req, 0, sizeof( req_args ) );
|
||||
memset32( Packet, 0, SS_DATA_LEN );
|
||||
|
||||
req->device_no = DeviceID;
|
||||
req->control.bmRequestType = USB_REQTYPE_INTERFACE_GET;
|
||||
req->control.bmRequest = USB_REQ_GETREPORT;
|
||||
req->control.wValue = (USB_REPTYPE_INPUT<<8) | 0x1;
|
||||
req->control.wIndex = 0x0;
|
||||
req->control.wLength = SS_DATA_LEN;
|
||||
req->data = Packet;
|
||||
|
||||
ret = IOS_Ioctl( HIDHandle, /*ControlMessage*/2, req, 32, 0, 0 );
|
||||
if( ret < 0 )
|
||||
{
|
||||
dbgprintf("HID:HIDPS3Read:IOS_Ioctl( %u, %u, %p, %u, %u, %u):%d\n", HIDHandle, 2, req, 32, 0, 0, ret );
|
||||
//Shutdown();
|
||||
}
|
||||
|
||||
if( !PS3LedSet && Packet[4] )
|
||||
{
|
||||
HIDPS3SetLED(1);
|
||||
PS3LedSet = 1;
|
||||
}
|
||||
if( HIDRumbleLast != *(vu32*)(0x12003010) )
|
||||
{
|
||||
HIDRumble( *(vu32*)(0x12003010) );
|
||||
HIDRumbleLast = *(vu32*)(0x12003010);
|
||||
}
|
||||
memcpy(HID_Packet, Packet, SS_DATA_LEN);
|
||||
sync_after_write(HID_Packet, SS_DATA_LEN);
|
||||
return;
|
||||
}
|
||||
void HIDIRQRead()
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
memset32( req, 0, sizeof( req_args ) );
|
||||
|
||||
req->device_no = DeviceID;
|
||||
req->interrupt.dLength = wMaxPacketSize;
|
||||
req->interrupt.endpoint = bEndpointAddress;
|
||||
req->data = Packet;
|
||||
|
||||
retry:
|
||||
ret = IOS_Ioctl( HIDHandle, /*InterruptMessageIN*/3, req, 32, 0, 0 );
|
||||
if( ret < 0 )
|
||||
{
|
||||
dbgprintf("ES:HIDIRQRead:IOS_Ioctl():%d\n", ret );
|
||||
Shutdown();
|
||||
}
|
||||
if(HID_CTRL->MultiIn && Packet[0] != HID_CTRL->MultiInValue)
|
||||
goto retry;
|
||||
memcpy(HID_Packet, Packet, wMaxPacketSize);
|
||||
sync_after_write(HID_Packet, wMaxPacketSize);
|
||||
return;
|
||||
}
|
||||
|
||||
void HIDRumble( u32 Enable )
|
||||
{
|
||||
if( HID_CTRL->Polltype == 0 )
|
||||
{
|
||||
switch( Enable )
|
||||
{
|
||||
case 0: // stop
|
||||
case 2: // hard stop
|
||||
HIDPS3SetRumble( 0, 0, 0, 0 );
|
||||
break;
|
||||
case 1: // start
|
||||
HIDPS3SetRumble( 0, 0xFF, 0, 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 ConfigGetValue( char *Data, const char *EntryName, u32 Entry )
|
||||
{
|
||||
char entryname[128];
|
||||
_sprintf( entryname, "\n%s=", EntryName );
|
||||
|
||||
char *str = strstr( Data, entryname );
|
||||
if( str == (char*)NULL )
|
||||
{
|
||||
dbgprintf("Entry:\"%s\" not found!\n", EntryName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
str += strlen(entryname); // Skip '='
|
||||
|
||||
if( Entry == 0 )
|
||||
{
|
||||
return atox(str);
|
||||
|
||||
} else if ( Entry == 1 ) {
|
||||
|
||||
str = strstr( str, "," );
|
||||
if( str == (char*)NULL )
|
||||
{
|
||||
dbgprintf("No \",\" found in entry.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
str++; //Skip ,
|
||||
|
||||
return atox(str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
u32 HID_Run(void *arg)
|
||||
{
|
||||
IOS_Close(HIDHandle);
|
||||
HIDHandle = IOS_Open("/dev/usb/hid", 0 );
|
||||
dbgprintf("HID_Run, waiting for signal\n");
|
||||
while(read32(0x12003004) == 0)
|
||||
{
|
||||
sync_before_read((void*)0x12003004, 0x20);
|
||||
mdelay(100);
|
||||
}
|
||||
dbgprintf("Starting HID Thread!\n");
|
||||
bool Polltype = HID_CTRL->Polltype;
|
||||
while(1)
|
||||
{
|
||||
if(Polltype)
|
||||
HIDIRQRead();
|
||||
else
|
||||
HIDPS3Read();
|
||||
mdelay(25);
|
||||
}
|
||||
return 0;
|
||||
}
|
140
kernel/HID.h
Normal file
140
kernel/HID.h
Normal file
@@ -0,0 +1,140 @@
|
||||
#ifndef __HID_H__
|
||||
#define __HID_H__
|
||||
|
||||
#include "global.h"
|
||||
#include "syscalls.h"
|
||||
#include "common.h"
|
||||
#include "vsprintf.h"
|
||||
#include "alloc.h"
|
||||
#include "PS3Controller.h"
|
||||
|
||||
typedef struct Layout
|
||||
{
|
||||
u32 Offset;
|
||||
u32 Mask;
|
||||
} layout;
|
||||
|
||||
typedef struct Controller
|
||||
{
|
||||
u32 VID;
|
||||
u32 PID;
|
||||
u32 Polltype;
|
||||
u32 DPAD;
|
||||
u32 DigitalLR;
|
||||
u32 MultiIn;
|
||||
u32 MultiInValue;
|
||||
|
||||
layout Power;
|
||||
|
||||
layout A;
|
||||
layout B;
|
||||
layout X;
|
||||
layout Y;
|
||||
layout Z;
|
||||
|
||||
layout L;
|
||||
layout R;
|
||||
layout S;
|
||||
|
||||
layout Left;
|
||||
layout Down;
|
||||
layout Right;
|
||||
layout Up;
|
||||
|
||||
layout RightUp;
|
||||
layout DownRight;
|
||||
layout DownLeft;
|
||||
layout UpLeft;
|
||||
|
||||
u32 StickX;
|
||||
u32 StickY;
|
||||
u32 CStickX;
|
||||
u32 CStickY;
|
||||
u32 LAnalog;
|
||||
u32 RAnalog;
|
||||
|
||||
} controller;
|
||||
|
||||
typedef struct _usbdevdesc
|
||||
{
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 bcdUSB;
|
||||
|
||||
u8 bDeviceClass;
|
||||
u8 bDeviceSubClass;
|
||||
u8 bDeviceProtocol;
|
||||
u8 bMaxPacketSize0;
|
||||
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
|
||||
u16 bcdDevice;
|
||||
u8 iManufacturer;
|
||||
u8 iProduct;
|
||||
|
||||
u8 iSerialNumber;
|
||||
u8 bNumConfigurations;
|
||||
u32 *configurations;
|
||||
} __attribute__((packed)) usb_devdesc;
|
||||
|
||||
|
||||
#define USB_REPTYPE_FEATURE 0x03
|
||||
#define USB_REPTYPE_OUTPUT 0x02
|
||||
#define USB_REPTYPE_INPUT 0x01
|
||||
|
||||
|
||||
#define USB_REQ_GETREPORT 0x01
|
||||
#define USB_REQ_GETDESCRIPTOR 0x06
|
||||
#define USB_REQ_SETREPORT 0x09
|
||||
|
||||
|
||||
/* control message request type bitmask */
|
||||
#define USB_CTRLTYPE_DIR_HOST2DEVICE (0<<7)
|
||||
#define USB_CTRLTYPE_DIR_DEVICE2HOST (1<<7)
|
||||
#define USB_CTRLTYPE_TYPE_STANDARD (0<<5)
|
||||
#define USB_CTRLTYPE_TYPE_CLASS (1<<5)
|
||||
#define USB_CTRLTYPE_TYPE_VENDOR (2<<5)
|
||||
#define USB_CTRLTYPE_TYPE_RESERVED (3<<5)
|
||||
#define USB_CTRLTYPE_REC_DEVICE 0
|
||||
#define USB_CTRLTYPE_REC_INTERFACE 1
|
||||
#define USB_CTRLTYPE_REC_ENDPOINT 2
|
||||
#define USB_CTRLTYPE_REC_OTHER 3
|
||||
|
||||
|
||||
#define USB_REQTYPE_INTERFACE_GET (USB_CTRLTYPE_DIR_DEVICE2HOST|USB_CTRLTYPE_TYPE_CLASS|USB_CTRLTYPE_REC_INTERFACE)
|
||||
#define USB_REQTYPE_INTERFACE_SET (USB_CTRLTYPE_DIR_HOST2DEVICE|USB_CTRLTYPE_TYPE_CLASS|USB_CTRLTYPE_REC_INTERFACE)
|
||||
|
||||
|
||||
typedef struct {
|
||||
u8 padding[16]; // anything you want can go here
|
||||
s32 device_no;
|
||||
union {
|
||||
struct {
|
||||
u8 bmRequestType;
|
||||
u8 bmRequest;
|
||||
u16 wValue;
|
||||
u16 wIndex;
|
||||
u16 wLength;
|
||||
} control;
|
||||
struct {
|
||||
u32 endpoint;
|
||||
u32 dLength;
|
||||
} interrupt;
|
||||
struct {
|
||||
u8 bIndex;
|
||||
} string;
|
||||
};
|
||||
void *data; // virtual pointer, not physical!
|
||||
} req_args; // 32 bytes
|
||||
|
||||
s32 HIDInit();
|
||||
void HIDPS3Init( void );
|
||||
void HIDPS3Read( void );
|
||||
void HIDRead( void );
|
||||
void HIDPS3SetLED( u8 led );
|
||||
void HIDRumble( u32 Enable );
|
||||
u32 ConfigGetValue( char *Data, const char *EntryName, u32 Entry );
|
||||
void HIDPS3SetRumble( u8 duration_right, u8 power_right, u8 duration_left, u8 power_left);
|
||||
u32 HID_Run(void *arg);
|
||||
#endif
|
59
kernel/Makefile
Normal file
59
kernel/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
PREFIX = $(DEVKITARM)/bin/arm-none-eabi-
|
||||
CC = $(PREFIX)gcc
|
||||
AS = $(PREFIX)as
|
||||
LD = $(PREFIX)gcc
|
||||
STRIP = $(PREFIX)strip
|
||||
|
||||
CFLAGS = -mbig-endian -fno-unwind-tables -fomit-frame-pointer -O2 -Wall -I. -mcpu=arm926ej-s -mthumb -fno-builtin-toupper -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-memcmp -fno-builtin-malloc -fno-builtin-free
|
||||
ASFLAGS = -mbig-endian -mcpu=arm926ej-s
|
||||
LDFLAGS = -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,kernel.ld,-Map,kernel.map -n
|
||||
LIBS = -lgcc
|
||||
|
||||
TARGET = kernel.elf
|
||||
OBJECTS = start.o common.o alloc.o gecko.o FST.o DI.o Patch.o StreamADPCM.o EXI.o ff.o HID.o diskio.o Config.o utils_asm.o ES.o NAND.o main.o syscalls.o vsprintf.o string.o
|
||||
ifeq ($(usb), 1)
|
||||
OBJECTS += tiny_ehci_glue.o usb_os.o
|
||||
CFLAGS += -DNINTENDONT_USB
|
||||
BINFILE = ../loader/data/kernel_usb.bin
|
||||
else
|
||||
OBJECTS += SDI.o
|
||||
CFLAGS += -UNINTENDONT_USB
|
||||
BINFILE = ../loader/data/kernel.bin
|
||||
endif
|
||||
|
||||
.PHONY: FORCE
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET) : kernel.ld $(OBJECTS)
|
||||
@echo "LD $@"
|
||||
@$(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
|
||||
@$(STRIP) kernel.elf
|
||||
@cp kernel.elf $(BINFILE)
|
||||
|
||||
%.o : %.s
|
||||
@echo "AS $@"
|
||||
@$(CC) $(CFLAGS) -D_LANGUAGE_ASSEMBLY -c -x assembler-with-cpp -o $@ $<
|
||||
|
||||
%.o : %.S
|
||||
@echo "AS $@"
|
||||
@$(CC) $(CFLAGS) -D_LANGUAGE_ASSEMBLY -c -x assembler-with-cpp -o $@ $<
|
||||
|
||||
%.o : %.c
|
||||
@echo "CC $@"
|
||||
@$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
%.d: %.c
|
||||
@echo "DEP $@"
|
||||
@set -e; $(CC) -M $(CFLAGS) $< \
|
||||
| sed 's?\($*\)\.o[ :]*?\1.o $@ : ?g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
%.d: %.S
|
||||
@echo "DEP $@"
|
||||
@touch $@
|
||||
|
||||
-include $(OBJECTS:.o=.d)
|
||||
|
||||
clean:
|
||||
-rm -f *.elf *.o *.bin *.d *.map
|
62
kernel/NAND.c
Normal file
62
kernel/NAND.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
|
||||
Nintendont (Kernel) - Playing Gamecubes in Wii mode on a Wii U
|
||||
|
||||
Copyright (C) 2013 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#include "NAND.h"
|
||||
|
||||
extern u8 *CNTMap;
|
||||
|
||||
u8 *NANDLoadFile( char *path, u32 *Size )
|
||||
{
|
||||
s32 fd = IOS_Open( path, 1 );
|
||||
if( fd < 0 )
|
||||
{
|
||||
//dbgprintf("ES:NANDLoadFile->IOS_Open(\"%s\", 1 ):%d\n", path, fd );
|
||||
*Size = fd;
|
||||
return (u8*)NULL;
|
||||
}
|
||||
//dbgprintf("ES:NANDLoadFile->IOS_Open(\"%s\", 1 ):%d\n", path, fd );
|
||||
|
||||
*Size = IOS_Seek( fd, 0, SEEK_END );
|
||||
//dbgprintf("ES:NANDLoadFile->Size:%d\n", *Size );
|
||||
|
||||
IOS_Seek( fd, 0, 0 );
|
||||
|
||||
u8 *data = (u8*)heap_alloc_aligned( 0, *Size, 0x40 );
|
||||
if( data == NULL )
|
||||
{
|
||||
//dbgprintf("ES:NANDLoadFile(\"%s\")->Failed to alloc %d bytes!\n", path, status->Size );
|
||||
IOS_Close( fd );
|
||||
return (u8*)NULL;
|
||||
}
|
||||
|
||||
s32 r = IOS_Read( fd, data, *Size );
|
||||
//dbgprintf("ES:NANDLoadFile->IOS_Read():%d\n", r );
|
||||
if( r < 0 )
|
||||
{
|
||||
//dbgprintf("ES:NANDLoadFile->IOS_Read():%d\n", r );
|
||||
*Size = r;
|
||||
IOS_Close( fd );
|
||||
return (u8*)NULL;
|
||||
}
|
||||
|
||||
IOS_Close( fd );
|
||||
|
||||
return data;
|
||||
}
|
33
kernel/NAND.h
Normal file
33
kernel/NAND.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
|
||||
SNEEK - SD-NAND/ES emulation kit for Nintendo Wii
|
||||
|
||||
Copyright (C) 2009-2011 crediar
|
||||
|
||||
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 version 2.
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
#ifndef __NAND_H__
|
||||
#define __NAND_H__
|
||||
|
||||
#include "global.h"
|
||||
#include "string.h"
|
||||
#include "syscalls.h"
|
||||
#include "global.h"
|
||||
#include "ipc.h"
|
||||
#include "common.h"
|
||||
|
||||
u8 *NANDLoadFile( char * path, u32 *Size );
|
||||
|
||||
#endif
|
107
kernel/PS3Controller.h
Normal file
107
kernel/PS3Controller.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef __PS3CONTROLLER_H__
|
||||
#define __PS3CONTROLLER_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#define SS_DATA_LEN 53 //Should be 49
|
||||
#define SS_LEDS_RUMBLE_LEN 32
|
||||
#define SS_VENDOR_ID 0x054C //Sony Corp.
|
||||
#define SS_PRODUCT_ID 0x0268 //Sixaxis and DS3
|
||||
#define SS_HEAP_SIZE 4096
|
||||
#define SS_DEV_MAX 7
|
||||
|
||||
struct SS_BUTTONS //Big endian
|
||||
{
|
||||
u8 left : 1;
|
||||
u8 down : 1;
|
||||
u8 right : 1;
|
||||
u8 up : 1;
|
||||
u8 start : 1;
|
||||
u8 R3 : 1;
|
||||
u8 L3 : 1;
|
||||
u8 select : 1;
|
||||
|
||||
u8 square : 1;
|
||||
u8 cross : 1;
|
||||
u8 circle : 1;
|
||||
u8 triangle : 1;
|
||||
u8 R1 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 L2 : 1;
|
||||
|
||||
u8 not_used : 7;
|
||||
u8 PS : 1;
|
||||
};
|
||||
|
||||
struct SS_ANALOG
|
||||
{
|
||||
u8 x;
|
||||
u8 y;
|
||||
};
|
||||
|
||||
struct SS_DPAD_SENSITIVE
|
||||
{
|
||||
u8 up;
|
||||
u8 right;
|
||||
u8 down;
|
||||
u8 left;
|
||||
};
|
||||
|
||||
struct SS_SHOULDER_SENSITIVE
|
||||
{
|
||||
u8 L2;
|
||||
u8 R2;
|
||||
u8 L1;
|
||||
u8 R1;
|
||||
};
|
||||
|
||||
struct SS_BUTTON_SENSITIVE
|
||||
{
|
||||
u8 triangle;
|
||||
u8 circle;
|
||||
u8 cross;
|
||||
u8 square;
|
||||
};
|
||||
|
||||
struct SS_MOTION
|
||||
{
|
||||
u16 accX;
|
||||
u16 accY;
|
||||
u16 accZ;
|
||||
u16 Zgyro;
|
||||
};
|
||||
struct SS_GAMEPAD
|
||||
{
|
||||
u8 HIDdata;
|
||||
u8 unk0;
|
||||
struct SS_BUTTONS buttons;
|
||||
u8 unk1;
|
||||
struct SS_ANALOG leftAnalog;
|
||||
struct SS_ANALOG rightAnalog;
|
||||
u32 unk2;
|
||||
struct SS_DPAD_SENSITIVE dpad_sens;
|
||||
struct SS_SHOULDER_SENSITIVE shoulder_sens;
|
||||
struct SS_BUTTON_SENSITIVE button_sens;
|
||||
u16 unk3;
|
||||
u8 unk4;
|
||||
u8 status;
|
||||
u8 power_rating;
|
||||
u8 comm_status;
|
||||
u32 unk5;
|
||||
u32 unk6;
|
||||
u8 unk7;
|
||||
struct SS_MOTION motion;
|
||||
u8 padding[3];
|
||||
}__attribute__((packed));
|
||||
|
||||
struct SickSaxis
|
||||
{
|
||||
struct SS_GAMEPAD gamepad;
|
||||
u8 leds_rumble[SS_LEDS_RUMBLE_LEN];
|
||||
u8 connected;
|
||||
|
||||
s32 fd, dev_id;
|
||||
};
|
||||
|
||||
#endif
|
1648
kernel/Patch.c
Normal file
1648
kernel/Patch.c
Normal file
File diff suppressed because it is too large
Load Diff
94
kernel/Patch.h
Normal file
94
kernel/Patch.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef __PATCH_H__
|
||||
#define __PATCH_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#define VI_NTSC 0
|
||||
#define VI_PAL 1
|
||||
#define VI_MPAL 2
|
||||
#define VI_DEBUG 3
|
||||
#define VI_DEBUG_PAL 4
|
||||
#define VI_EUR60 5
|
||||
|
||||
#define GXPal528IntDf 0
|
||||
#define GXEurgb60Hz480IntDf 1
|
||||
#define GXMpal480IntDf 2
|
||||
#define GXNtsc480IntDf 3
|
||||
#define GXNtsc480Int 4
|
||||
#define GXNtsc480Prog 5
|
||||
#define GXPal528Prog 6
|
||||
#define GXEurgb60Hz480Prog 7
|
||||
|
||||
typedef struct PatchInfo
|
||||
{
|
||||
u8 *Signature;
|
||||
u8 *Mask;
|
||||
u32 Length;
|
||||
u32 FunctionLength;
|
||||
u8 *Patch;
|
||||
u32 PatchLength;
|
||||
char *Name;
|
||||
} PatchInfo;
|
||||
|
||||
typedef struct FuncPattern
|
||||
{
|
||||
u32 Length;
|
||||
u32 Loads;
|
||||
u32 Stores;
|
||||
u32 FCalls;
|
||||
u32 Branch;
|
||||
u32 Moves;
|
||||
const u8 *Patch;
|
||||
u32 PatchLength;
|
||||
const char *Name;
|
||||
u32 Group;
|
||||
u32 Found;
|
||||
} FuncPattern;
|
||||
|
||||
typedef struct GC_SRAM
|
||||
{
|
||||
/* 0x00 */ u16 CheckSum1;
|
||||
/* 0x02 */ u16 CheckSum2;
|
||||
/* 0x04 */ u32 ead0;
|
||||
/* 0x08 */ u32 ead1;
|
||||
/* 0x0C */ u32 CounterBias;
|
||||
/* 0x10 */ u8 DisplayOffsetH;
|
||||
/* 0x11 */ u8 BootMode; // Bit 6 PAL60 flag
|
||||
/* 0x12 */ u8 Language;
|
||||
/* 0x13 */ u8 Flags;
|
||||
/*
|
||||
bit desc 0 1
|
||||
0 -\_ Video mode
|
||||
1 -/
|
||||
2 Sound mode Mono Stereo
|
||||
3 always 1
|
||||
4 always 0
|
||||
5 always 1
|
||||
6 ?
|
||||
7 Prog mode off on
|
||||
*/
|
||||
/* 0x14 */ u8 FlashID[2][12];
|
||||
/* 0x2C */ u32 WirelessKBID;
|
||||
/* 0x30 */ u16 WirlessPADID[4];
|
||||
/* 0x38 */ u8 LastDVDError;
|
||||
/* 0x39 */ u8 Reserved;
|
||||
/* 0x3A */ u8 FlashIDChecksum[2];
|
||||
/* 0x3E */ u16 Unused;
|
||||
} GC_SRAM;
|
||||
|
||||
|
||||
void PatchB( u32 dst, u32 src );
|
||||
void PatchBL( u32 dst, u32 src );
|
||||
void PatchFunc( char *ptr );
|
||||
void PatchFuncAI( char *dst, u32 Length );
|
||||
|
||||
void DoCardPatches( char *ptr, u32 size );
|
||||
void DoPatches( char *Buffer, u32 Length, u32 Offset );
|
||||
|
||||
void MPattern( u8 *Data, u32 Length, FuncPattern *FunctionPattern );
|
||||
int CPattern( FuncPattern *FPatA, FuncPattern *FPatB );
|
||||
|
||||
void write32A( u32 Offset, u32 Value, u32 CurrentValue, u32 ShowAssert );
|
||||
void SRAM_Checksum( unsigned short *buf, unsigned short *c1, unsigned short *c2);
|
||||
|
||||
#endif
|
316
kernel/PatchCodes.h
Normal file
316
kernel/PatchCodes.h
Normal file
@@ -0,0 +1,316 @@
|
||||
#ifndef __PATCHCODES_H__
|
||||
#define __PATCHCODES_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#if 1
|
||||
|
||||
#ifndef EXIPATCH
|
||||
|
||||
#include "asm/__CARDSync.h"
|
||||
#include "asm/CARDCheck.h"
|
||||
#include "asm/CARDCheckAsync.h"
|
||||
#include "asm/CARDCheckEX.h"
|
||||
#include "asm/CARDClose.h"
|
||||
#include "asm/CARDCreate.h"
|
||||
#include "asm/CARDDelete.h"
|
||||
#include "asm/CARDFastOpen.h"
|
||||
#include "asm/CARDFreeBlocks.h"
|
||||
#include "asm/CARDGetEncoding.h"
|
||||
#include "asm/CARDGetMemSize.h"
|
||||
#include "asm/CARDGetSerialNo.h"
|
||||
#include "asm/CARDGetStats.h"
|
||||
#include "asm/CARDMount.h"
|
||||
#include "asm/CARDMountAsync.h"
|
||||
#include "asm/CARDOpen.h"
|
||||
#include "asm/CARDProbe.h"
|
||||
#include "asm/CARDProbeEX.h"
|
||||
#include "asm/CARDRead.h"
|
||||
#include "asm/CARDSetStats.h"
|
||||
#include "asm/CARDWrite.h"
|
||||
#include "asm/CARDGetResultCode.h"
|
||||
#include "asm/CARDGetXferredBytes.h"
|
||||
#include "asm/CARDFastDelete.h"
|
||||
#include "asm/CARDRename.h"
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#include "asm/EXIImm.h"
|
||||
#include "asm/EXISelect.h"
|
||||
#include "asm/EXILock.h"
|
||||
#include "asm/EXIDMA.h"
|
||||
#include "asm/EXIProbe.h"
|
||||
#include "asm/EXIGetID.h"
|
||||
#include "asm/__CARDReadStatus.h"
|
||||
#include "asm/__CARDEraseSector.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include "asm/SITransfer.h"
|
||||
|
||||
#include "asm/ARQPostRequest.h"
|
||||
#include "asm/AXSetVoiceState.h"
|
||||
#include "asm/AXSetVoiceAdr.h"
|
||||
#include "asm/ARInit.h"
|
||||
#include "asm/ARGetBaseAddress.h"
|
||||
#include "asm/ARStartDMA.h"
|
||||
#include "asm/SIGetType.h"
|
||||
#include "asm/__OSInitSRAM.h"
|
||||
#include "asm/__OSReadROM.h"
|
||||
#include "asm/FakeInterrupt.h"
|
||||
#include "asm/TCIntrruptHandler.h"
|
||||
//#include "asm/FakeAIInterrupt.h"
|
||||
#include "asm/APRCallback.h"
|
||||
#include "asm/PADRead.h"
|
||||
#include "asm/PADControlMotor.h"
|
||||
#include "asm/DCInvalidateRange.h"
|
||||
|
||||
unsigned char SRAM[64] =
|
||||
{
|
||||
0x42, 0x8B,
|
||||
0xBD, 0x71,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x17, 0xCA, 0x2A, 0x85,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x3C,
|
||||
0x9B, 0x58, 0x5A, 0xB5, 0xB6,0xC7, 0x92, 0xB7, 0x55,0x49, 0xC6, 0x0B,
|
||||
0x4A, 0x09, 0x00, 0x45, 0x0D,0x00, 0xB2, 0x1D, 0x41,0x03, 0x88, 0x1D,
|
||||
0x49, 0x41, 0x50, 0x04,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0xFE,
|
||||
0x00,
|
||||
0xC8, 0xC8,
|
||||
0x01, 0x05,
|
||||
0x57, 0x28,
|
||||
} ;
|
||||
|
||||
const u32 __GXSetVAT_patch[31] = {
|
||||
/*0x8122ce00,*/ 0x39400000, 0x896904f2, 0x7d284b78,
|
||||
0x556007ff, 0x41820050, 0x38e00008, 0x3cc0cc01,
|
||||
0x98e68000, 0x61400070, 0x61440080, 0x61430090,
|
||||
0x98068000, 0x38000000, 0x80a8001c, 0x90a68000,
|
||||
0x98e68000, 0x98868000, 0x8088003c, 0x90868000,
|
||||
0x98e68000, 0x98668000, 0x8068005c, 0x90668000,
|
||||
0x98068000, 0x556bf87f, 0x394a0001, 0x39080004,
|
||||
0x4082ffa0, 0x38000000, 0x980904f2, 0x4e800020
|
||||
};
|
||||
|
||||
const u8 GXMObjects[][0x3C] =
|
||||
{
|
||||
{ // GXPal528IntDf
|
||||
0x00, 0x00, 0x00, 0x04, 0x02, 0x80, 0x02, 0x10, 0x02, 0x10, 0x00, 0x28, 0x00, 0x17, 0x02, 0x80,
|
||||
0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x08, 0x08, 0x0A, 0x0C, 0x0A, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXEurgb60Hz480IntDf
|
||||
0x00, 0x00, 0x00, 0x14, 0x02, 0x80, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x28, 0x00, 0x00, 0x02, 0x80,
|
||||
0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x08, 0x08, 0x0A, 0x0C, 0x0A, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXMpal480IntDf
|
||||
0x00, 0x00, 0x00, 0x08, 0x02, 0x80, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x28, 0x00, 0x00, 0x02, 0x80,
|
||||
0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x08, 0x08, 0x0A, 0x0C, 0x0A, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXNtsc480IntDf
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x28, 0x00, 0x00, 0x02, 0x80,
|
||||
0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x08, 0x08, 0x0A, 0x0C, 0x0A, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXNtsc480Int
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x28, 0x00, 0x00, 0x02, 0x80,
|
||||
0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x00, 0x00, 0x15, 0x16, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXNtsc480Prog
|
||||
0x00, 0x00, 0x00, 0x02, 0x02, 0x80, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x28, 0x00, 0x00, 0x02, 0x80,
|
||||
0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x00, 0x00, 0x15, 0x16, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXPal528Prog
|
||||
0x00, 0x00, 0x00, 0x06, 0x02, 0x80, 0x02, 0x10, 0x02, 0x10, 0x00, 0x28, 0x00, 0x17, 0x02, 0x80,
|
||||
0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x00, 0x00, 0x15, 0x16, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
|
||||
{ // GXEurgb60Hz480Prog
|
||||
0x00, 0x00, 0x00, 0x16, 0x02, 0x80, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x28, 0x00, 0x00, 0x02, 0x80,
|
||||
0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x00, 0x00, 0x15, 0x16, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned char patch_fwrite_GC[144] = // actually wii
|
||||
{
|
||||
0x7C, 0x85, 0x21, 0xD7, 0x40, 0x81, 0x00, 0x84, 0x3C, 0xE0, 0xCD, 0x00, 0x3D, 0x40, 0xCD, 0x00,
|
||||
0x3D, 0x60, 0xCD, 0x00, 0x60, 0xE7, 0x68, 0x14, 0x61, 0x4A, 0x68, 0x24, 0x61, 0x6B, 0x68, 0x20,
|
||||
0x38, 0xC0, 0x00, 0x00, 0x7C, 0x06, 0x18, 0xAE, 0x54, 0x00, 0xA0, 0x16, 0x64, 0x08, 0xB0, 0x00,
|
||||
0x38, 0x00, 0x00, 0xD0, 0x90, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x06, 0xAC, 0x91, 0x0A, 0x00, 0x00,
|
||||
0x7C, 0x00, 0x06, 0xAC, 0x38, 0x00, 0x00, 0x19, 0x90, 0x0B, 0x00, 0x00, 0x7C, 0x00, 0x06, 0xAC,
|
||||
0x80, 0x0B, 0x00, 0x00, 0x7C, 0x00, 0x04, 0xAC, 0x70, 0x09, 0x00, 0x01, 0x40, 0x82, 0xFF, 0xF4,
|
||||
0x80, 0x0A, 0x00, 0x00, 0x7C, 0x00, 0x04, 0xAC, 0x39, 0x20, 0x00, 0x00, 0x91, 0x27, 0x00, 0x00,
|
||||
0x7C, 0x00, 0x06, 0xAC, 0x74, 0x09, 0x04, 0x00, 0x41, 0x82, 0xFF, 0xB8, 0x38, 0xC6, 0x00, 0x01,
|
||||
0x7F, 0x86, 0x20, 0x00, 0x40, 0x9E, 0xFF, 0xA0, 0x7C, 0xA3, 0x2B, 0x78, 0x4E, 0x80, 0x00, 0x20,
|
||||
};
|
||||
|
||||
// Audio streaming replacement functions copied from Swiss r92
|
||||
const u32 __dvdLowAudioStatusNULL[17] = {
|
||||
// execute function(1); passed in on r4
|
||||
0x9421FFC0, // stwu sp, -0x0040 (sp)
|
||||
0x7C0802A6, // mflr r0
|
||||
0x90010000, // stw r0, 0 (sp)
|
||||
0x7C8903A6, // mtctr r4
|
||||
0x3C80CC00, // lis r4, 0xCC00
|
||||
0x2E830000, // cmpwi cr5, r3, 0
|
||||
0x4196000C, // beq- cr5, +0xC ?
|
||||
0x38600001, // li r3, 1
|
||||
0x48000008, // b +0x8 ?
|
||||
0x38600000, // li r3, 0
|
||||
0x90646020, // stw r3, 0x6020 (r4)
|
||||
0x38600001, // li r3, 1
|
||||
0x4E800421, // bctrl
|
||||
0x80010000, // lwz r0, 0 (sp)
|
||||
0x7C0803A6, // mtlr r0
|
||||
0x38210040, // addi sp, sp, 64
|
||||
0x4E800020 // blr
|
||||
};
|
||||
|
||||
const u32 __dvdLowAudioConfigNULL[10] = {
|
||||
// execute callback(1); passed in on r5 without actually touching the drive!
|
||||
0x9421FFC0, // stwu sp, -0x0040 (sp)
|
||||
0x7C0802A6, // mflr r0
|
||||
0x90010000, // stw r0, 0 (sp)
|
||||
0x7CA903A6, // mtctr r5
|
||||
0x38600001, // li r3, 1
|
||||
0x4E800421, // bctrl
|
||||
0x80010000, // lwz r0, 0 (sp)
|
||||
0x7C0803A6, // mtlr r0
|
||||
0x38210040, // addi sp, sp, 64
|
||||
0x4E800020 // blr
|
||||
};
|
||||
|
||||
const u32 __dvdLowReadAudioNULL[] = {
|
||||
// execute callback(1); passed in on r6 without actually touching the drive!
|
||||
0x9421FFC0, // stwu sp, -0x0040 (sp)
|
||||
0x7C0802A6, // mflr r0
|
||||
0x90010000, // stw r0, 0 (sp)
|
||||
0x7CC903A6, // mtctr r6
|
||||
0x38600001, // li r3, 1
|
||||
0x4E800421, // bctr;
|
||||
0x80010000, // lwz r0, 0 (sp)
|
||||
0x7C0803A6, // mtlr r0
|
||||
0x38210040, // addi sp, sp, 64
|
||||
0x4E800020
|
||||
};
|
||||
|
||||
const unsigned char DVDInquiryAsync[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00,
|
||||
0x90, 0x03, 0x00, 0x00, 0x90, 0x03, 0x00, 0x04, 0x90, 0x03, 0x00, 0x0C, 0x90, 0x03, 0x00, 0x10,
|
||||
0x38, 0x00, 0x00, 0x02, 0x90, 0x03, 0x00, 0x08, 0x38, 0x00, 0x00, 0x20, 0x90, 0x03, 0x00, 0x1C,
|
||||
0x90, 0x03, 0x00, 0x20, 0x90, 0x03, 0x00, 0x14, 0x90, 0x83, 0x00, 0x18, 0x90, 0xA3, 0x00, 0x28,
|
||||
0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x23, 0xAC, 0x38, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x02,
|
||||
0x2C, 0x05, 0x00, 0x00, 0x41, 0x82, 0x00, 0x14, 0x7C, 0xA9, 0x03, 0xA6, 0x7C, 0x64, 0x1B, 0x78,
|
||||
0x38, 0x60, 0x00, 0x20, 0x4E, 0x80, 0x04, 0x21, 0x38, 0x60, 0x00, 0x01, 0x80, 0x01, 0x00, 0x08,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
||||
|
||||
const unsigned char DVDSeekAbsAsyncPrio[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00,
|
||||
0x90, 0x03, 0x00, 0x00, 0x90, 0x03, 0x00, 0x04, 0x90, 0x03, 0x00, 0x1C, 0x38, 0x00, 0x00, 0x02,
|
||||
0x90, 0x03, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00, 0x90, 0x03, 0x00, 0x0C, 0x90, 0x83, 0x00, 0x10,
|
||||
0x90, 0xA3, 0x00, 0x28, 0x2C, 0x05, 0x00, 0x00, 0x41, 0x82, 0x00, 0x14, 0x7C, 0xA9, 0x03, 0xA6,
|
||||
0x7C, 0x64, 0x1B, 0x78, 0x38, 0x60, 0x00, 0x00, 0x4E, 0x80, 0x04, 0x21, 0x38, 0x60, 0x00, 0x01,
|
||||
0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
||||
|
||||
const unsigned char DVDReadAbsAsyncPrio[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x7F, 0xA3, 0xEB, 0x78,
|
||||
0x80, 0x83, 0x00, 0x18, 0x38, 0x00, 0x00, 0x00, 0x3D, 0x00, 0xC0, 0x00, 0x39, 0x08, 0x2F, 0x00,
|
||||
0x7C, 0x00, 0x43, 0xAC, 0x54, 0xA8, 0xD9, 0x7E, 0x7D, 0x09, 0x03, 0xA6, 0x7C, 0x88, 0x23, 0x78,
|
||||
0x7C, 0x00, 0x43, 0xAC, 0x39, 0x08, 0x00, 0x20, 0x42, 0x00, 0xFF, 0xF8, 0x3D, 0x00, 0xC0, 0x00,
|
||||
0x3C, 0x00, 0xA7, 0x00, 0x90, 0x08, 0x2F, 0x08, 0x54, 0xC0, 0xF0, 0xBE, 0x90, 0x08, 0x2F, 0x0C,
|
||||
0x90, 0x88, 0x2F, 0x14, 0x90, 0xA8, 0x2F, 0x10, 0x90, 0xA8, 0x2F, 0x18, 0x90, 0x68, 0x2F, 0x24,
|
||||
0x38, 0x00, 0x00, 0x03, 0x90, 0x08, 0x2F, 0x1C, 0x90, 0xA3, 0x00, 0x1C, 0x90, 0xA3, 0x00, 0x14,
|
||||
0x90, 0xA3, 0x00, 0x20, 0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
||||
|
||||
|
||||
const u32 DVDGetDriveStatus[] = {
|
||||
0x38600000, // li r3, 0
|
||||
0x4E800020
|
||||
};
|
||||
|
||||
const u32 __OSDispatchInterruptPattern1[] =
|
||||
{
|
||||
0x5483077A, 0x28030000, 0x41820008, 0x64002000
|
||||
};
|
||||
const u32 __OSDispatchInterruptPattern2[] =
|
||||
{
|
||||
0x57C0077A, 0x28000000, 0x41820008, 0x67FF2000
|
||||
};
|
||||
|
||||
const unsigned char DVDRead[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00,
|
||||
0x3C, 0xE0, 0xC0, 0x00, 0x38, 0xE7, 0x2F, 0x00, 0x7C, 0x00, 0x3B, 0xAC, 0x54, 0xA7, 0xD9, 0x7E,
|
||||
0x7C, 0xE9, 0x03, 0xA6, 0x7C, 0x87, 0x23, 0x78, 0x7C, 0x00, 0x3B, 0xAC, 0x38, 0xE7, 0x00, 0x20,
|
||||
0x42, 0x00, 0xFF, 0xF8, 0x3C, 0xE0, 0xC0, 0x00, 0x3C, 0x00, 0xA8, 0x00, 0x90, 0x07, 0x2F, 0x08,
|
||||
0x80, 0x03, 0x00, 0x30, 0x7C, 0xC0, 0x32, 0x14, 0x54, 0xC0, 0xF0, 0xBE, 0x90, 0x07, 0x2F, 0x0C,
|
||||
0x90, 0x87, 0x2F, 0x14, 0x90, 0xA7, 0x2F, 0x10, 0x90, 0xA7, 0x2F, 0x18, 0x38, 0x00, 0x00, 0x03,
|
||||
0x90, 0x07, 0x2F, 0x1C, 0x80, 0x07, 0x2F, 0x1C, 0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8,
|
||||
0x80, 0x07, 0x2F, 0x30, 0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4,
|
||||
0x38, 0x00, 0x00, 0x00, 0x90, 0x03, 0x00, 0x00, 0x90, 0x03, 0x00, 0x04, 0x90, 0x03, 0x00, 0x0C,
|
||||
0x38, 0x00, 0x00, 0x01, 0x90, 0x03, 0x00, 0x08, 0x90, 0xC3, 0x00, 0x10, 0x90, 0x83, 0x00, 0x18,
|
||||
0x90, 0xA3, 0x00, 0x1C, 0x90, 0xA3, 0x00, 0x14, 0x90, 0xA3, 0x00, 0x20, 0x7C, 0xA3, 0x2B, 0x78,
|
||||
0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
||||
|
||||
const unsigned char DVDReadAsync[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x90, 0xE3, 0x00, 0x28,
|
||||
0x38, 0x00, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x00, 0x38, 0xE7, 0x2F, 0x00, 0x7C, 0x00, 0x3B, 0xAC,
|
||||
0x54, 0xA7, 0xD9, 0x7E, 0x7C, 0xE9, 0x03, 0xA6, 0x7C, 0x87, 0x23, 0x78, 0x7C, 0x00, 0x3B, 0xAC,
|
||||
0x38, 0xE7, 0x00, 0x20, 0x42, 0x00, 0xFF, 0xF8, 0x3C, 0xE0, 0xC0, 0x00, 0x3C, 0x00, 0xA9, 0x00,
|
||||
0x90, 0x07, 0x2F, 0x08, 0x80, 0x03, 0x00, 0x30, 0x7C, 0xC0, 0x32, 0x14, 0x54, 0xC0, 0xF0, 0xBE,
|
||||
0x90, 0x07, 0x2F, 0x0C, 0x90, 0x87, 0x2F, 0x14, 0x90, 0xA7, 0x2F, 0x10, 0x90, 0xA7, 0x2F, 0x18,
|
||||
0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x1C, 0x80, 0x07, 0x2F, 0x1C, 0x2C, 0x00, 0x00, 0x03,
|
||||
0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x30, 0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00,
|
||||
0x41, 0x82, 0xFF, 0xF4, 0x38, 0x00, 0x00, 0x00, 0x90, 0x03, 0x00, 0x00, 0x90, 0x03, 0x00, 0x04,
|
||||
0x90, 0x03, 0x00, 0x0C, 0x38, 0x00, 0x00, 0x01, 0x90, 0x03, 0x00, 0x08, 0x90, 0xC3, 0x00, 0x10,
|
||||
0x90, 0xA3, 0x00, 0x1C, 0x80, 0x03, 0x00, 0x34, 0x90, 0x03, 0x00, 0x14, 0x90, 0x03, 0x00, 0x20,
|
||||
0x90, 0x83, 0x00, 0x18, 0x81, 0x83, 0x00, 0x28, 0x2C, 0x0C, 0x00, 0x00, 0x41, 0x82, 0x00, 0x14,
|
||||
0x7D, 0x89, 0x03, 0xA6, 0x7C, 0x64, 0x1B, 0x78, 0x7C, 0xA3, 0x2B, 0x78, 0x4E, 0x80, 0x04, 0x21,
|
||||
0x38, 0x60, 0x00, 0x01, 0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
528
kernel/SDI.c
Normal file
528
kernel/SDI.c
Normal file
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
Hardware routines for reading and writing to the Wii's internal
|
||||
SD slot.
|
||||
|
||||
Copyright (c) 2008-2013
|
||||
Michael Wiedenbauer (shagkur)
|
||||
Dave Murphy (WinterMute)
|
||||
Sven Peter <svpe@gmx.net>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
#include "SDI.h"
|
||||
#include "vsprintf.h"
|
||||
#include "alloc.h"
|
||||
|
||||
#ifndef DEBUG_SD
|
||||
#define dbgprintf(...)
|
||||
#else
|
||||
extern int dbgprintf( const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
s32 SDHandle;
|
||||
u16 SDRCA;
|
||||
u8 SDCID[16];
|
||||
u32 IsSDHC;
|
||||
|
||||
s32 __sd0_fd;
|
||||
static u16 __sd0_rca;
|
||||
static s32 __sd0_initialized;
|
||||
static s32 __sd0_sdhc;
|
||||
//static u8 __sd0_csd[16];
|
||||
static u8 __sd0_cid[16];
|
||||
|
||||
static s32 __sdio_initialized;
|
||||
|
||||
static u8 *rw_buffer;
|
||||
|
||||
static char _sd0_fs[] = "/dev/sdio/slot0";
|
||||
|
||||
vector *iovec;
|
||||
struct _sdiorequest *request;
|
||||
struct _sdioresponse *response;
|
||||
|
||||
static s32 __sdio_sendcommand(u32 cmd,u32 cmd_type,u32 rsp_type,u32 arg,u32 blk_cnt,u32 blk_size,void *buffer,void *reply,u32 rlen)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
request->cmd = cmd;
|
||||
request->cmd_type = cmd_type;
|
||||
request->rsp_type = rsp_type;
|
||||
request->arg = arg;
|
||||
request->blk_cnt = blk_cnt;
|
||||
request->blk_size = blk_size;
|
||||
request->dma_addr = buffer;
|
||||
request->isdma = ((buffer!=NULL)?1:0);
|
||||
request->pad0 = 0;
|
||||
|
||||
if(request->isdma || __sd0_sdhc == 1)
|
||||
{
|
||||
iovec[0].data = (u32)request;
|
||||
iovec[0].len = sizeof(struct _sdiorequest);
|
||||
iovec[1].data = (u32)buffer;
|
||||
iovec[1].len = (blk_size*blk_cnt);
|
||||
iovec[2].data = (u32)response;
|
||||
iovec[2].len = sizeof(struct _sdioresponse);
|
||||
ret = IOS_Ioctlv(__sd0_fd,IOCTL_SDIO_SENDCMD,2,1,iovec);
|
||||
} else
|
||||
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_SENDCMD,request,sizeof(struct _sdiorequest),response,sizeof(struct _sdioresponse));
|
||||
|
||||
if(reply && !(rlen>16))
|
||||
memcpy(reply,response,rlen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sdio_setclock(u32 set)
|
||||
{
|
||||
s32 ret;
|
||||
u32 *clock = (u32*)malloc( sizeof(u32) );
|
||||
|
||||
*clock = set;
|
||||
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_SETCLK,clock,sizeof(u32),NULL,0);
|
||||
|
||||
free(clock);
|
||||
return ret;
|
||||
}
|
||||
u32 *status = NULL;
|
||||
s32 __sdio_getstatus()
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_GETSTATUS,NULL,0,status,sizeof(u32));
|
||||
if(ret<0) return ret;
|
||||
|
||||
return *status;
|
||||
}
|
||||
static s32 __sdio_resetcard()
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
__sd0_rca = 0;
|
||||
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_RESETCARD,NULL,0,status,sizeof(u32));
|
||||
if(ret<0) return ret;
|
||||
|
||||
__sd0_rca = (u16)(*status>>16);
|
||||
return (*status&0xffff);
|
||||
}
|
||||
static s32 __sdio_gethcr(u8 reg, u8 size, u32 *val)
|
||||
{
|
||||
s32 ret;
|
||||
u32 *hcr_value = (u32*)malloc( sizeof(u32) );
|
||||
u32 *hcr_query = (u32*)malloc( sizeof(u32) * 6 );
|
||||
|
||||
if(val==NULL) return -4;
|
||||
|
||||
*hcr_value = 0;
|
||||
*val = 0;
|
||||
hcr_query[0] = reg;
|
||||
hcr_query[1] = 0;
|
||||
hcr_query[2] = 0;
|
||||
hcr_query[3] = size;
|
||||
hcr_query[4] = 0;
|
||||
hcr_query[5] = 0;
|
||||
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_READHCREG,(void*)hcr_query,24,hcr_value,sizeof(u32));
|
||||
*val = *hcr_value;
|
||||
|
||||
free( hcr_value );
|
||||
free( hcr_query );
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sdio_sethcr(u8 reg, u8 size, u32 data)
|
||||
{
|
||||
s32 ret;
|
||||
u32 *hcr_query = (u32*)malloc( sizeof(u32) * 6 );
|
||||
|
||||
hcr_query[0] = reg;
|
||||
hcr_query[1] = 0;
|
||||
hcr_query[2] = 0;
|
||||
hcr_query[3] = size;
|
||||
hcr_query[4] = data;
|
||||
hcr_query[5] = 0;
|
||||
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_WRITEHCREG,(void*)hcr_query,24,NULL,0);
|
||||
|
||||
free( hcr_query );
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sdio_waithcr(u8 reg, u8 size, u8 unset, u32 mask)
|
||||
{
|
||||
u32 val;
|
||||
s32 ret;
|
||||
s32 tries = 10;
|
||||
|
||||
while(tries-- > 0)
|
||||
{
|
||||
ret = __sdio_gethcr(reg, size, &val);
|
||||
if(ret < 0) return ret;
|
||||
if((unset && !(val & mask)) || (!unset && (val & mask))) return 0;
|
||||
udelay(10000);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
static s32 __sdio_setbuswidth(u32 bus_width)
|
||||
{
|
||||
s32 ret;
|
||||
u32 hc_reg = 0;
|
||||
|
||||
ret = __sdio_gethcr(SDIOHCR_HOSTCONTROL, 1, &hc_reg);
|
||||
if(ret<0) return ret;
|
||||
|
||||
hc_reg &= 0xff;
|
||||
hc_reg &= ~SDIOHCR_HOSTCONTROL_4BIT;
|
||||
if(bus_width==4) hc_reg |= SDIOHCR_HOSTCONTROL_4BIT;
|
||||
|
||||
return __sdio_sethcr(SDIOHCR_HOSTCONTROL, 1, hc_reg);
|
||||
}
|
||||
static s32 __sd0_getrca()
|
||||
{
|
||||
s32 ret;
|
||||
u32 rca;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_SENDRCA,0,SDIO_RESPONSE_R5,0,0,0,NULL,&rca,sizeof(rca));
|
||||
if(ret<0) return ret;
|
||||
|
||||
__sd0_rca = (u16)(rca>>16);
|
||||
return (rca&0xffff);
|
||||
}
|
||||
static s32 __sd0_select()
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_SELECT,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1B,(__sd0_rca<<16),0,0,NULL,NULL,0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sd0_deselect()
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_DESELECT,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1B,0,0,0,NULL,NULL,0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sd0_setblocklength(u32 blk_len)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_SETBLOCKLEN,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,blk_len,0,0,NULL,NULL,0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sd0_setbuswidth(u32 bus_width)
|
||||
{
|
||||
u16 val;
|
||||
s32 ret;
|
||||
|
||||
val = 0x0000;
|
||||
if(bus_width==4) val = 0x0002;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_APPCMD,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,(__sd0_rca<<16),0,0,NULL,NULL,0);
|
||||
if(ret<0) return ret;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_ACMD_SETBUSWIDTH,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,val,0,0,NULL,NULL,0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static s32 __sd0_getcid()
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_ALL_SENDCID,0,SDIO_RESPOSNE_R2,(__sd0_rca<<16),0,0,NULL,__sd0_cid,16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
s32 SDHCInit()
|
||||
{
|
||||
s32 ret;
|
||||
s32 tries;
|
||||
status = (u32*)malloc(sizeof(u32));
|
||||
struct _sdioresponse resp;
|
||||
|
||||
dbgprintf("SDHCInit()\n");
|
||||
|
||||
__sd0_rca = 0;
|
||||
__sd0_initialized = 0;
|
||||
__sd0_sdhc = 0;
|
||||
__sdio_initialized = 0;
|
||||
|
||||
rw_buffer = (u8*)malloc( 4 * 1024 );
|
||||
|
||||
iovec = (vector*)malloc( sizeof(vector) * 3 );
|
||||
request = (struct _sdiorequest*)malloc( sizeof(struct _sdiorequest) );
|
||||
response = (struct _sdioresponse*)malloc( sizeof(struct _sdioresponse) );
|
||||
|
||||
dbgprintf("SD:Heap:%X\n", rw_buffer );
|
||||
|
||||
__sd0_fd = IOS_Open(_sd0_fs,1);
|
||||
if ( __sd0_fd < 0 )
|
||||
{
|
||||
dbgprintf("Failed to SD\n");
|
||||
return __sd0_fd;
|
||||
}
|
||||
|
||||
__sdio_resetcard();
|
||||
__sdio_getstatus();
|
||||
|
||||
if(!((*status)&SDIO_STATUS_CARD_INSERTED))
|
||||
return false;
|
||||
|
||||
if(!((*status)&SDIO_STATUS_CARD_INITIALIZED))
|
||||
{
|
||||
// IOS doesn't like this card, so we need to convice it to accept it.
|
||||
|
||||
// reopen the handle which makes IOS clean stuff up
|
||||
IOS_Close(__sd0_fd);
|
||||
__sd0_fd = IOS_Open(_sd0_fs,1);
|
||||
|
||||
// reset the host controller
|
||||
if(__sdio_sethcr(SDIOHCR_SOFTWARERESET, 1, 7) < 0) goto fail;
|
||||
if(__sdio_waithcr(SDIOHCR_SOFTWARERESET, 1, 1, 7) < 0) goto fail;
|
||||
|
||||
// initialize interrupts (sd_reset_card does this on success)
|
||||
__sdio_sethcr(0x34, 4, 0x13f00c3);
|
||||
__sdio_sethcr(0x38, 4, 0x13f00c3);
|
||||
|
||||
// enable power
|
||||
__sd0_sdhc = 1;
|
||||
ret = __sdio_sethcr(SDIOHCR_POWERCONTROL, 1, 0xe);
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sdio_sethcr(SDIOHCR_POWERCONTROL, 1, 0xf);
|
||||
if(ret < 0) goto fail;
|
||||
|
||||
// enable internal clock, wait until it gets stable and enable sd clock
|
||||
ret = __sdio_sethcr(SDIOHCR_CLOCKCONTROL, 2, 0);
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sdio_sethcr(SDIOHCR_CLOCKCONTROL, 2, 0x101);
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sdio_waithcr(SDIOHCR_CLOCKCONTROL, 2, 0, 2);
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sdio_sethcr(SDIOHCR_CLOCKCONTROL, 2, 0x107);
|
||||
if(ret < 0) goto fail;
|
||||
|
||||
// setup timeout
|
||||
ret = __sdio_sethcr(SDIOHCR_TIMEOUTCONTROL, 1, SDIO_DEFAULT_TIMEOUT);
|
||||
if(ret < 0) goto fail;
|
||||
|
||||
// standard SDHC initialization process
|
||||
ret = __sdio_sendcommand(SDIO_CMD_GOIDLE, 0, 0, 0, 0, 0, NULL, NULL, 0);
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sdio_sendcommand(SDIO_CMD_SENDIFCOND, 0, SDIO_RESPONSE_R6, 0x1aa, 0, 0, NULL, &resp, sizeof(resp));
|
||||
if(ret < 0) goto fail;
|
||||
if((resp.rsp_fields[0] & 0xff) != 0xaa) goto fail;
|
||||
|
||||
tries = 10;
|
||||
while(tries-- > 0)
|
||||
{
|
||||
ret = __sdio_sendcommand(SDIO_CMD_APPCMD, SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,0,0,0,NULL,NULL,0);
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sdio_sendcommand(SDIO_ACMD_SENDOPCOND, 0, SDIO_RESPONSE_R3, 0x40300000, 0, 0, NULL, &resp, sizeof(resp));
|
||||
if(ret < 0) goto fail;
|
||||
if(resp.rsp_fields[0] & (1 << 31)) break;
|
||||
|
||||
udelay(10000);
|
||||
}
|
||||
if(tries < 0) goto fail;
|
||||
|
||||
// FIXME: SDv2 cards which are not high-capacity won't work :/
|
||||
if(resp.rsp_fields[0] & (1 << 30))
|
||||
__sd0_sdhc = 1;
|
||||
else
|
||||
__sd0_sdhc = 0;
|
||||
|
||||
ret = __sd0_getcid();
|
||||
if(ret < 0) goto fail;
|
||||
ret = __sd0_getrca();
|
||||
if(ret < 0) goto fail;
|
||||
}
|
||||
else if((*status)&SDIO_STATUS_CARD_SDHC)
|
||||
__sd0_sdhc = 1;
|
||||
else
|
||||
__sd0_sdhc = 0;
|
||||
|
||||
ret = __sdio_setbuswidth(4);
|
||||
if(ret<0) return false;
|
||||
|
||||
ret = __sdio_setclock(1);
|
||||
if(ret<0) return false;
|
||||
|
||||
ret = __sd0_select();
|
||||
if(ret<0) return false;
|
||||
|
||||
ret = __sd0_setblocklength(PAGE_SIZE512);
|
||||
if(ret<0) {
|
||||
ret = __sd0_deselect();
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = __sd0_setbuswidth(4);
|
||||
if(ret<0) {
|
||||
ret = __sd0_deselect();
|
||||
return false;
|
||||
}
|
||||
__sd0_deselect();
|
||||
|
||||
__sd0_initialized = 1;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
dbgprintf("SDInit failed\n");
|
||||
__sdio_sethcr(SDIOHCR_SOFTWARERESET, 1, 7);
|
||||
__sdio_waithcr(SDIOHCR_SOFTWARERESET, 1, 1, 7);
|
||||
IOS_Close(__sd0_fd);
|
||||
__sd0_fd = IOS_Open(_sd0_fs,1);
|
||||
return false;
|
||||
}
|
||||
void SDHCShutdown( void )
|
||||
{
|
||||
free(iovec);
|
||||
free(request);
|
||||
free(response);
|
||||
}
|
||||
bool sdio_ReadSectors(sec_t sector, sec_t numSectors, void* buffer )
|
||||
{
|
||||
s32 ret;
|
||||
u8 *ptr;
|
||||
sec_t blk_off;
|
||||
|
||||
if(buffer==NULL)
|
||||
return false;
|
||||
|
||||
ret = __sd0_select();
|
||||
if(ret<0)
|
||||
return false;
|
||||
|
||||
if((u32)buffer & 0x1F)
|
||||
{
|
||||
ptr = (u8*)buffer;
|
||||
|
||||
int secs_to_read;
|
||||
|
||||
while( numSectors > 0 )
|
||||
{
|
||||
if(__sd0_sdhc == 0)
|
||||
blk_off = (sector*PAGE_SIZE512);
|
||||
else
|
||||
blk_off = sector;
|
||||
|
||||
if(numSectors > 8)
|
||||
secs_to_read = 8;
|
||||
else
|
||||
secs_to_read = numSectors;
|
||||
|
||||
|
||||
sync_before_read( rw_buffer, secs_to_read * 512 );
|
||||
_ahbMemFlush(9);
|
||||
|
||||
ret = __sdio_sendcommand( SDIO_CMD_READMULTIBLOCK, SDIOCMD_TYPE_AC, SDIO_RESPONSE_R1, blk_off, secs_to_read, PAGE_SIZE512, rw_buffer, NULL, 0 );
|
||||
if( ret >= 0 )
|
||||
{
|
||||
memcpy( ptr, rw_buffer, PAGE_SIZE512*secs_to_read );
|
||||
sync_after_write( ptr, PAGE_SIZE512*secs_to_read );
|
||||
|
||||
ptr += PAGE_SIZE512*secs_to_read;
|
||||
sector += secs_to_read;
|
||||
numSectors -= secs_to_read;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
if(__sd0_sdhc == 0)
|
||||
sector *= PAGE_SIZE512;
|
||||
|
||||
sync_before_read( buffer, numSectors * PAGE_SIZE512 );
|
||||
_ahbMemFlush(9);
|
||||
|
||||
ret = __sdio_sendcommand( SDIO_CMD_READMULTIBLOCK, SDIOCMD_TYPE_AC, SDIO_RESPONSE_R1, sector, numSectors, PAGE_SIZE512, buffer, NULL, 0 );
|
||||
|
||||
sync_after_write( buffer, numSectors * PAGE_SIZE512 );
|
||||
|
||||
}
|
||||
|
||||
__sd0_deselect();
|
||||
|
||||
return (ret>=0);
|
||||
}
|
||||
|
||||
bool sdio_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer)
|
||||
{
|
||||
s32 ret;
|
||||
u8 *ptr;
|
||||
u32 blk_off;
|
||||
|
||||
if(buffer==NULL)
|
||||
return false;
|
||||
|
||||
ret = __sd0_select();
|
||||
if(ret<0)
|
||||
return false;
|
||||
|
||||
if((u32)buffer & 0x1F)
|
||||
{
|
||||
ptr = (u8*)buffer;
|
||||
int secs_to_write;
|
||||
|
||||
while(numSectors>0)
|
||||
{
|
||||
if(__sd0_sdhc == 0)
|
||||
blk_off = (sector*PAGE_SIZE512);
|
||||
else
|
||||
blk_off = sector;
|
||||
if(numSectors > 8)
|
||||
secs_to_write = 8;
|
||||
else
|
||||
secs_to_write = numSectors;
|
||||
|
||||
memcpy( rw_buffer, ptr, PAGE_SIZE512*secs_to_write );
|
||||
|
||||
sync_after_write( rw_buffer, PAGE_SIZE512*secs_to_write );
|
||||
_ahbMemFlush(9);
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_WRITEMULTIBLOCK,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,blk_off,secs_to_write,PAGE_SIZE512,rw_buffer,NULL,0);
|
||||
if(ret>=0)
|
||||
{
|
||||
ptr += PAGE_SIZE512*secs_to_write;
|
||||
sector+=secs_to_write;
|
||||
numSectors-=secs_to_write;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
if(__sd0_sdhc == 0)
|
||||
sector *= PAGE_SIZE512;
|
||||
|
||||
sync_after_write( (void*)buffer, PAGE_SIZE512 );
|
||||
_ahbMemFlush(9);
|
||||
|
||||
ret = __sdio_sendcommand(SDIO_CMD_WRITEMULTIBLOCK,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,sector,numSectors,PAGE_SIZE512,(char *)buffer,NULL,0);
|
||||
|
||||
}
|
||||
|
||||
__sd0_deselect();
|
||||
|
||||
return (ret>=0);
|
||||
}
|
97
kernel/SDI.h
Normal file
97
kernel/SDI.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef __SDI_H__
|
||||
#define __SDI_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#define SDIO_HEAPSIZE (5*1024)
|
||||
|
||||
#define PAGE_SIZE512 512
|
||||
|
||||
#define SDIOHCR_RESPONSE 0x10
|
||||
#define SDIOHCR_HOSTCONTROL 0x28
|
||||
#define SDIOHCR_POWERCONTROL 0x29
|
||||
#define SDIOHCR_CLOCKCONTROL 0x2c
|
||||
#define SDIOHCR_TIMEOUTCONTROL 0x2e
|
||||
#define SDIOHCR_SOFTWARERESET 0x2f
|
||||
|
||||
#define SDIOHCR_HOSTCONTROL_4BIT 0x02
|
||||
|
||||
#define SDIO_DEFAULT_TIMEOUT 0xe
|
||||
|
||||
#define IOCTL_SDIO_WRITEHCREG 0x01
|
||||
#define IOCTL_SDIO_READHCREG 0x02
|
||||
#define IOCTL_SDIO_READCREG 0x03
|
||||
#define IOCTL_SDIO_RESETCARD 0x04
|
||||
#define IOCTL_SDIO_WRITECREG 0x05
|
||||
#define IOCTL_SDIO_SETCLK 0x06
|
||||
#define IOCTL_SDIO_SENDCMD 0x07
|
||||
#define IOCTL_SDIO_SETBUSWIDTH 0x08
|
||||
#define IOCTL_SDIO_READMCREG 0x09
|
||||
#define IOCTL_SDIO_WRITEMCREG 0x0A
|
||||
#define IOCTL_SDIO_GETSTATUS 0x0B
|
||||
#define IOCTL_SDIO_GETOCR 0x0C
|
||||
#define IOCTL_SDIO_READDATA 0x0D
|
||||
#define IOCTL_SDIO_WRITEDATA 0x0E
|
||||
|
||||
#define SDIOCMD_TYPE_BC 1
|
||||
#define SDIOCMD_TYPE_BCR 2
|
||||
#define SDIOCMD_TYPE_AC 3
|
||||
#define SDIOCMD_TYPE_ADTC 4
|
||||
|
||||
#define SDIO_RESPONSE_NONE 0
|
||||
#define SDIO_RESPONSE_R1 1
|
||||
#define SDIO_RESPONSE_R1B 2
|
||||
#define SDIO_RESPOSNE_R2 3
|
||||
#define SDIO_RESPONSE_R3 4
|
||||
#define SDIO_RESPONSE_R4 5
|
||||
#define SDIO_RESPONSE_R5 6
|
||||
#define SDIO_RESPONSE_R6 7
|
||||
|
||||
#define SDIO_CMD_GOIDLE 0x00
|
||||
#define SDIO_CMD_ALL_SENDCID 0x02
|
||||
#define SDIO_CMD_SENDRCA 0x03
|
||||
#define SDIO_CMD_SELECT 0x07
|
||||
#define SDIO_CMD_DESELECT 0x07
|
||||
#define SDIO_CMD_SENDIFCOND 0x08
|
||||
#define SDIO_CMD_SENDCSD 0x09
|
||||
#define SDIO_CMD_SENDCID 0x0A
|
||||
#define SDIO_CMD_SENDSTATUS 0x0D
|
||||
#define SDIO_CMD_SETBLOCKLEN 0x10
|
||||
#define SDIO_CMD_READBLOCK 0x11
|
||||
#define SDIO_CMD_READMULTIBLOCK 0x12
|
||||
#define SDIO_CMD_WRITEBLOCK 0x18
|
||||
#define SDIO_CMD_WRITEMULTIBLOCK 0x19
|
||||
#define SDIO_CMD_APPCMD 0x37
|
||||
|
||||
#define SDIO_ACMD_SETBUSWIDTH 0x06
|
||||
#define SDIO_ACMD_SENDSCR 0x33
|
||||
#define SDIO_ACMD_SENDOPCOND 0x29
|
||||
|
||||
#define SDIO_STATUS_CARD_INSERTED 0x1
|
||||
#define SDIO_STATUS_CARD_INITIALIZED 0x10000
|
||||
#define SDIO_STATUS_CARD_SDHC 0x100000
|
||||
|
||||
struct _sdioresponse
|
||||
{
|
||||
u32 rsp_fields[3];
|
||||
u32 acmd12_response;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
s32 SDHCInit( void );
|
||||
bool sdio_ReadSectors(sec_t sector, sec_t numSectors,void* buffer);
|
||||
bool sdio_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer);
|
||||
|
||||
#endif
|
111
kernel/StreamADPCM.c
Normal file
111
kernel/StreamADPCM.c
Normal file
@@ -0,0 +1,111 @@
|
||||
// Adapted from in_cube by hcs & destop
|
||||
|
||||
#include "StreamADPCM.h"
|
||||
|
||||
#ifdef AUDIOSTREAM
|
||||
// Convert Gamecube DTK/TRK/ADP tracks (essentially CD-XA ADPCM) to the
|
||||
// nearest equivalent "DSP" ADPCM.
|
||||
|
||||
void transcode_frame(const char * framebuf, int channel, char * outframe)
|
||||
{
|
||||
int chanshift = (channel == 0 ? 0 : 4);
|
||||
uint8_t adp_frame_header = framebuf[0 + channel];
|
||||
int scale_log = 12 - (adp_frame_header & 0xf);
|
||||
int predictor = adp_frame_header >> 4;
|
||||
|
||||
// CHECK_ERROR(scale_log < 0 || scale_log > 16, "scale range");
|
||||
uint8_t dsp_frame_header = scale_log | (predictor << 4);
|
||||
|
||||
// uint8_t outframe[16];
|
||||
outframe[0] = outframe[8] = dsp_frame_header;
|
||||
|
||||
int i,j,k;
|
||||
|
||||
for (j = 0, k = 4; j < 2; j++) {
|
||||
for (i = 0; i < 14; i += 2, k += 2) {
|
||||
uint8_t sample = (framebuf[k] >> chanshift) & 0xf;
|
||||
uint8_t b = sample << 4;
|
||||
|
||||
sample = (framebuf[k+1] >> chanshift) & 0xf;
|
||||
b |= sample;
|
||||
|
||||
outframe[j*8 + 1 + i/2] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
s32 adpcm_history1_32;
|
||||
s32 adpcm_history2_32;
|
||||
|
||||
/* signed nibbles come up a lot */
|
||||
static int nibble_to_int[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1};
|
||||
|
||||
static inline int get_high_nibble_signed(u8 n) {
|
||||
/*return ((n&0x70)-(n&0x80))>>4;*/
|
||||
return nibble_to_int[n>>4];
|
||||
}
|
||||
|
||||
static inline int get_low_nibble_signed(u8 n) {
|
||||
/*return (n&7)-(n&8);*/
|
||||
return nibble_to_int[n&0xf];
|
||||
}
|
||||
|
||||
static inline int clamp16(s32 val) {
|
||||
if (val>32767) return 32767;
|
||||
if (val<-32768) return -32768;
|
||||
return val;
|
||||
}
|
||||
void decode_ngc_dtk( u8 *stream, u16 * outbuf, int channelspacing, s32 first_sample, s32 samples_to_do, int channel)
|
||||
{
|
||||
int i=first_sample;
|
||||
s32 sample_count;
|
||||
|
||||
int framesin = first_sample/28;
|
||||
|
||||
u8 q = stream[framesin*32+channel];
|
||||
s32 hist1 = 0;
|
||||
s32 hist2 = 0;
|
||||
|
||||
first_sample = first_sample%28;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing)
|
||||
{
|
||||
int sample_byte = stream[framesin*32+4+i];
|
||||
|
||||
s32 hist=0;
|
||||
|
||||
switch (q>>4)
|
||||
{
|
||||
case 0:
|
||||
hist = 0;
|
||||
break;
|
||||
case 1:
|
||||
hist = (hist1 * 0x3c);
|
||||
break;
|
||||
case 2:
|
||||
hist = (hist1 * 0x73) - (hist2 * 0x34);
|
||||
break;
|
||||
case 3:
|
||||
hist = (hist1 * 0x62) - (hist2 * 0x37);
|
||||
break;
|
||||
}
|
||||
|
||||
hist = (hist+0x20)>>6;
|
||||
if (hist > 0x1fffff) hist = 0x1fffff;
|
||||
if (hist < -0x200000) hist = -0x200000;
|
||||
|
||||
hist2 = hist1;
|
||||
|
||||
hist1 = ((((channel==0?
|
||||
get_low_nibble_signed(sample_byte):
|
||||
get_high_nibble_signed(sample_byte)
|
||||
) << 12) >> (q & 0xf)) << 6) + hist;
|
||||
|
||||
outbuf[sample_count] = clamp16(hist1 >> 6);
|
||||
}
|
||||
|
||||
adpcm_history1_32 = hist1;
|
||||
adpcm_history2_32 = hist2;
|
||||
}
|
||||
#endif
|
39
kernel/StreamADPCM.h
Normal file
39
kernel/StreamADPCM.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
// Adapted from in_cube by hcs & destop
|
||||
|
||||
#ifndef __STREAMADPCM_H__
|
||||
#define __STREAMADPCM_H__
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ONE_BLOCK_SIZE = 32,
|
||||
SAMPLES_PER_BLOCK = 28
|
||||
};
|
||||
|
||||
#ifdef AUDIOSTREAM
|
||||
|
||||
void decode_ngc_dtk( u8 *stream, u16 * outbuf, int channelspacing, s32 first_sample, s32 samples_to_do, int channel);
|
||||
void transcode_frame(const char * framebuf, int channel, char * outframe);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
19
kernel/WPad.h
Normal file
19
kernel/WPad.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __WPAD_H__
|
||||
#define __WPAD_H__
|
||||
|
||||
#define WPAD_BUTTON_LEFT 0x0001
|
||||
#define WPAD_BUTTON_RIGHT 0x0002
|
||||
#define WPAD_BUTTON_DOWN 0x0004
|
||||
#define WPAD_BUTTON_UP 0x0008
|
||||
#define WPAD_BUTTON_PLUS 0x0010
|
||||
|
||||
#define WPAD_BUTTON_2 0x0100
|
||||
#define WPAD_BUTTON_1 0x0200
|
||||
#define WPAD_BUTTON_B 0x0400
|
||||
#define WPAD_BUTTON_A 0x0800
|
||||
#define WPAD_BUTTON_MINUS 0x1000
|
||||
#define WPAD_BUTTON_Z 0x2000
|
||||
#define WPAD_BUTTON_C 0x4000
|
||||
#define WPAD_BUTTON_HOME 0x8000
|
||||
|
||||
#endif
|
33
kernel/alloc.c
Normal file
33
kernel/alloc.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "alloc.h"
|
||||
#include "vsprintf.h"
|
||||
#include "debug.h"
|
||||
|
||||
void *malloc( u32 size )
|
||||
{
|
||||
void *ptr = heap_alloc( 0, size );
|
||||
if( ptr == NULL )
|
||||
{
|
||||
//dbgprintf("Malloc:%p Size:%08X FAILED\n", ptr, size );
|
||||
Shutdown();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
void *malloca( u32 size, u32 align )
|
||||
{
|
||||
void *ptr = heap_alloc_aligned( 0, size, align );
|
||||
if( ptr == NULL )
|
||||
{
|
||||
//dbgprintf("Malloca:%p Size:%08X FAILED\n", ptr, size );
|
||||
Shutdown();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
void free( void *ptr )
|
||||
{
|
||||
if( ptr != NULL )
|
||||
heap_free( 0, ptr );
|
||||
|
||||
//dbgprintf("Free:%p\n", ptr );
|
||||
|
||||
return;
|
||||
}
|
9
kernel/alloc.h
Normal file
9
kernel/alloc.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __ALLOC_H__
|
||||
#define __ALLOC_H__
|
||||
|
||||
#include "syscalls.h"
|
||||
|
||||
void *malloc( u32 size );
|
||||
void *malloca( u32 size, u32 align );
|
||||
void free( void *ptr );
|
||||
#endif
|
66
kernel/asm/AIInitDMA.S
Normal file
66
kernel/asm/AIInitDMA.S
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <asm.h>
|
||||
|
||||
#in
|
||||
# r3 u32 ptr
|
||||
# r4 u32 length
|
||||
|
||||
#out
|
||||
# 0xD0B0 0000
|
||||
|
||||
AIInitDMA:
|
||||
stwu %sp, -0x10(%sp)
|
||||
mflr %r0
|
||||
stw %r0, 8(%sp)
|
||||
|
||||
lis %r5, 0xC000
|
||||
lwz %r5, 0x14(%r5) # StreamBufferOffset
|
||||
cmpwi %r5, 0
|
||||
beq end
|
||||
|
||||
mr %r7, %r4 #save length
|
||||
mr %r8, %r3 #save ptr
|
||||
|
||||
oris %r3, %r3, 0x8000
|
||||
|
||||
lwz %r0, 0(%r5)
|
||||
stw %r0, 0(%r3)
|
||||
addic. %r4, %r4, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r5)
|
||||
stwu %r0, 4(%r3)
|
||||
addic. %r4, %r4, -4
|
||||
bne memcpy
|
||||
|
||||
#store new offset
|
||||
lis %r4, 0xC000
|
||||
addi %r5, %r5, 4
|
||||
lwz %r0, 0x18(%r4) # StreamBufferENDOffset
|
||||
cmpw %r5, %r0
|
||||
ble NotDone
|
||||
|
||||
li %r5, 0
|
||||
NotDone:
|
||||
stw %r5, 0x14(%r4) # StreamBufferOffset
|
||||
|
||||
oris %r3, %r8, 0x8000
|
||||
srwi %r4, %r7, 5
|
||||
mtctr %r4
|
||||
|
||||
li %r0, 0
|
||||
DCFlushRange:
|
||||
dcbf %r0, %r3
|
||||
addi %r3, %r3, 0x20
|
||||
bdnz DCFlushRange
|
||||
|
||||
mr %r4, %r7
|
||||
mr %r3, %r8
|
||||
|
||||
end:
|
||||
lwz %r0, 8(%sp)
|
||||
mtlr %r0
|
||||
addi %sp, %sp, 0x10
|
||||
|
||||
addi %r30, %r3, 0
|
||||
|
||||
blr
|
20
kernel/asm/AIInitDMA.h
Normal file
20
kernel/asm/AIInitDMA.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Filename : AIInitDMA.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define AIInitDMA_size 0x98
|
||||
|
||||
const unsigned char AIInitDMA[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x3C, 0xA0, 0xC0, 0x00,
|
||||
0x80, 0xA5, 0x00, 0x14, 0x2C, 0x05, 0x00, 0x00, 0x41, 0x82, 0x00, 0x6C, 0x7C, 0x87, 0x23, 0x78,
|
||||
0x7C, 0x68, 0x1B, 0x78, 0x64, 0x63, 0x80, 0x00, 0x80, 0x05, 0x00, 0x00, 0x90, 0x03, 0x00, 0x00,
|
||||
0x34, 0x84, 0xFF, 0xFC, 0x84, 0x05, 0x00, 0x04, 0x94, 0x03, 0x00, 0x04, 0x34, 0x84, 0xFF, 0xFC,
|
||||
0x40, 0x82, 0xFF, 0xF4, 0x3C, 0x80, 0xC0, 0x00, 0x38, 0xA5, 0x00, 0x04, 0x80, 0x04, 0x00, 0x18,
|
||||
0x7C, 0x05, 0x00, 0x00, 0x40, 0x81, 0x00, 0x08, 0x38, 0xA0, 0x00, 0x00, 0x90, 0xA4, 0x00, 0x14,
|
||||
0x65, 0x03, 0x80, 0x00, 0x54, 0xE4, 0xD9, 0x7E, 0x7C, 0x89, 0x03, 0xA6, 0x38, 0x00, 0x00, 0x00,
|
||||
0x7C, 0x00, 0x18, 0xAC, 0x38, 0x63, 0x00, 0x20, 0x42, 0x00, 0xFF, 0xF8, 0x7C, 0xE4, 0x3B, 0x78,
|
||||
0x7D, 0x03, 0x43, 0x78, 0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10,
|
||||
0x3B, 0xC3, 0x00, 0x00, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
41
kernel/asm/APRCallback.S
Normal file
41
kernel/asm/APRCallback.S
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <asm.h>
|
||||
|
||||
APRCallback:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x38(%sp)
|
||||
stw %r3, 0x34(%sp)
|
||||
|
||||
lis %r3, 0xC000
|
||||
lwz %r4, 0x0050(%r3)
|
||||
cmpwi %r4, 0
|
||||
beq end
|
||||
li %r0, 0
|
||||
stw %r0, 0x0050(%r3)
|
||||
|
||||
lwz %r4, -0x64e8(%r13)
|
||||
mtctr %r4
|
||||
# lwz %r3, 0x0054(%r3)
|
||||
bctrl
|
||||
|
||||
end:
|
||||
|
||||
lwz %r3, 0x34(%sp)
|
||||
|
||||
OSRestoreInterrupts:
|
||||
cmpwi %r3, 0
|
||||
mfmsr %r4
|
||||
beq loc_80304644
|
||||
ori %r5, %r4, 0x8000
|
||||
b loc_80304648
|
||||
loc_80304644:
|
||||
rlwinm %r5, %r4, 0,17,15
|
||||
loc_80304648:
|
||||
mtmsr %r5
|
||||
extrwi %r3, %r4, 1,16
|
||||
|
||||
lwz %r0, 0x3C(%sp)
|
||||
addi %sp, %sp, 0x38
|
||||
mtlr %r0
|
||||
blr
|
17
kernel/asm/APRCallback.h
Normal file
17
kernel/asm/APRCallback.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Filename : APRCallback.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define APRCallback_size 0x68
|
||||
|
||||
const unsigned char APRCallback[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xC8, 0x90, 0x61, 0x00, 0x34,
|
||||
0x3C, 0x60, 0xC0, 0x00, 0x80, 0x83, 0x00, 0x50, 0x2C, 0x04, 0x00, 0x00, 0x41, 0x82, 0x00, 0x18,
|
||||
0x38, 0x00, 0x00, 0x00, 0x90, 0x03, 0x00, 0x50, 0x80, 0x8D, 0x9B, 0x18, 0x7C, 0x89, 0x03, 0xA6,
|
||||
0x4E, 0x80, 0x04, 0x21, 0x80, 0x61, 0x00, 0x34, 0x2C, 0x03, 0x00, 0x00, 0x7C, 0x80, 0x00, 0xA6,
|
||||
0x41, 0x82, 0x00, 0x0C, 0x60, 0x85, 0x80, 0x00, 0x48, 0x00, 0x00, 0x08, 0x54, 0x85, 0x04, 0x5E,
|
||||
0x7C, 0xA0, 0x01, 0x24, 0x54, 0x83, 0x8F, 0xFE, 0x80, 0x01, 0x00, 0x3C, 0x38, 0x21, 0x00, 0x38,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
6
kernel/asm/ARGetBaseAddress.S
Normal file
6
kernel/asm/ARGetBaseAddress.S
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <asm.h>
|
||||
|
||||
ARGetBaseAddress:
|
||||
lis %r3, 0x2000
|
||||
oris %r3, %r3, 0x4000
|
||||
blr
|
11
kernel/asm/ARGetBaseAddress.h
Normal file
11
kernel/asm/ARGetBaseAddress.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
Filename : ARGetBaseAddress.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define ARGetBaseAddress_size 0xc
|
||||
|
||||
const unsigned char ARGetBaseAddress[] = {
|
||||
|
||||
0x3C, 0x60, 0x20, 0x00, 0x64, 0x63, 0x40, 0x00, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
9
kernel/asm/ARInit.S
Normal file
9
kernel/asm/ARInit.S
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <asm.h>
|
||||
|
||||
ARInit:
|
||||
oris %r3, %r3, 0x2000
|
||||
blr
|
||||
|
||||
lis %r0, 0x2000
|
||||
ori %r0, %r0, 0x4000
|
||||
blr
|
12
kernel/asm/ARInit.h
Normal file
12
kernel/asm/ARInit.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Filename : ARInit.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define ARInit_size 0x14
|
||||
|
||||
const unsigned char ARInit[] = {
|
||||
|
||||
0x64, 0x63, 0x20, 0x00, 0x4E, 0x80, 0x00, 0x20, 0x3C, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
116
kernel/asm/ARQPostRequest.S
Normal file
116
kernel/asm/ARQPostRequest.S
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <asm.h>
|
||||
|
||||
#in
|
||||
# r3 request
|
||||
# r4 owner don't care
|
||||
# r5 type
|
||||
# r6 prio don't care
|
||||
# r7 source
|
||||
# r8 dest
|
||||
# r9 length
|
||||
# r10 cb
|
||||
|
||||
#out
|
||||
# none
|
||||
|
||||
ARQPostRequest:
|
||||
stwu %sp, -0x10(%sp)
|
||||
mflr %r0
|
||||
stw %r0, 8(%sp)
|
||||
|
||||
## fill updated ARQRequest
|
||||
li %r0, 0
|
||||
stw %r0, 0x00(%r3) # struct ARQRequest* next
|
||||
stw %r0, 0x18(%r3) # u32 length
|
||||
|
||||
stw %r4, 0x04(%r3) # u32 owner
|
||||
stw %r5, 0x08(%r3) # u32 type
|
||||
stw %r6, 0x0C(%r3) # u32 priority
|
||||
|
||||
add %r0, %r7, %r9
|
||||
stw %r0, 0x10(%r3) # u32 source
|
||||
|
||||
add %r0, %r8, %r9
|
||||
stw %r0, 0x14(%r3) # u32 dest
|
||||
|
||||
stw %r10, 0x1C(%r3) # ARQCallback callback
|
||||
|
||||
lis %r4, 0x0FFF
|
||||
ori %r4, %r4, 0xFFFF
|
||||
|
||||
cmpwi %r5, 1
|
||||
beq ARAM_TO_MRAM
|
||||
|
||||
MRAM_TO_ARAM:
|
||||
and %r8, %r8, %r4
|
||||
addis %r8, %r8, 0x9000 # mem2
|
||||
|
||||
#DCInvalidateRange
|
||||
srwi %r4, %r9, 5
|
||||
mtctr %r4
|
||||
mr %r4, %r7
|
||||
|
||||
li %r0, 0
|
||||
DCInvalidateRangeA:
|
||||
dcbi %r0, %r4
|
||||
addi %r4, %r4, 0x20
|
||||
bdnz DCInvalidateRangeA
|
||||
|
||||
memcpy_pre:
|
||||
mr %r4, %r9 # save length
|
||||
|
||||
lwz %r0, 0(%r7)
|
||||
stw %r0, 0(%r8)
|
||||
addic. %r9, %r9, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r7)
|
||||
stwu %r0, 4(%r8)
|
||||
addic. %r9, %r9, -4
|
||||
bne memcpy
|
||||
|
||||
#restore offset
|
||||
addi %r8, %r8, 4
|
||||
sub %r8, %r8, %r4
|
||||
|
||||
#DCFlushRange
|
||||
srwi %r4, %r4, 5
|
||||
mtctr %r4
|
||||
mr %r4, %r8
|
||||
|
||||
li %r0, 0
|
||||
DCFlushRangeA:
|
||||
dcbf %r0, %r4
|
||||
addi %r4, %r4, 0x20
|
||||
bdnz DCFlushRangeA
|
||||
|
||||
cmpwi %r10, 0
|
||||
beq end
|
||||
|
||||
mtctr %r10
|
||||
bctrl
|
||||
|
||||
end:
|
||||
|
||||
lwz %r0, 8(%sp)
|
||||
mtlr %r0
|
||||
addi %sp, %sp, 0x10
|
||||
|
||||
blr
|
||||
|
||||
ARAM_TO_MRAM:
|
||||
and %r7, %r7, %r4
|
||||
addis %r7, %r7, 0x9000 # mem2
|
||||
|
||||
#DCFlushRange
|
||||
srwi %r4, %r9, 5
|
||||
mtctr %r4
|
||||
mr %r4, %r7
|
||||
|
||||
li %r0, 0
|
||||
DCFlushRangeB:
|
||||
dcbf %r0, %r4
|
||||
addi %r4, %r4, 0x20
|
||||
bdnz DCFlushRangeB
|
||||
|
||||
b memcpy_pre
|
26
kernel/asm/ARQPostRequest.h
Normal file
26
kernel/asm/ARQPostRequest.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Filename : ARQPostRequest.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define ARQPostRequest_size 0xf8
|
||||
|
||||
const unsigned char ARQPostRequest[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00,
|
||||
0x90, 0x03, 0x00, 0x00, 0x90, 0x03, 0x00, 0x18, 0x90, 0x83, 0x00, 0x04, 0x90, 0xA3, 0x00, 0x08,
|
||||
0x90, 0xC3, 0x00, 0x0C, 0x7C, 0x07, 0x4A, 0x14, 0x90, 0x03, 0x00, 0x10, 0x7C, 0x08, 0x4A, 0x14,
|
||||
0x90, 0x03, 0x00, 0x14, 0x91, 0x43, 0x00, 0x1C, 0x3C, 0x80, 0x0F, 0xFF, 0x60, 0x84, 0xFF, 0xFF,
|
||||
0x2C, 0x05, 0x00, 0x01, 0x41, 0x82, 0x00, 0x8C, 0x7D, 0x08, 0x20, 0x38, 0x3D, 0x08, 0x90, 0x00,
|
||||
0x55, 0x24, 0xD9, 0x7E, 0x7C, 0x89, 0x03, 0xA6, 0x7C, 0xE4, 0x3B, 0x78, 0x38, 0x00, 0x00, 0x00,
|
||||
0x7C, 0x00, 0x23, 0xAC, 0x38, 0x84, 0x00, 0x20, 0x42, 0x00, 0xFF, 0xF8, 0x7D, 0x24, 0x4B, 0x78,
|
||||
0x80, 0x07, 0x00, 0x00, 0x90, 0x08, 0x00, 0x00, 0x35, 0x29, 0xFF, 0xFC, 0x84, 0x07, 0x00, 0x04,
|
||||
0x94, 0x08, 0x00, 0x04, 0x35, 0x29, 0xFF, 0xFC, 0x40, 0x82, 0xFF, 0xF4, 0x39, 0x08, 0x00, 0x04,
|
||||
0x7D, 0x04, 0x40, 0x50, 0x54, 0x84, 0xD9, 0x7E, 0x7C, 0x89, 0x03, 0xA6, 0x7D, 0x04, 0x43, 0x78,
|
||||
0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x20, 0xAC, 0x38, 0x84, 0x00, 0x20, 0x42, 0x00, 0xFF, 0xF8,
|
||||
0x2C, 0x0A, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x7D, 0x49, 0x03, 0xA6, 0x4E, 0x80, 0x04, 0x21,
|
||||
0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x10, 0x4E, 0x80, 0x00, 0x20,
|
||||
0x7C, 0xE7, 0x20, 0x38, 0x3C, 0xE7, 0x90, 0x00, 0x55, 0x24, 0xD9, 0x7E, 0x7C, 0x89, 0x03, 0xA6,
|
||||
0x7C, 0xE4, 0x3B, 0x78, 0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x20, 0xAC, 0x38, 0x84, 0x00, 0x20,
|
||||
0x42, 0x00, 0xFF, 0xF8, 0x4B, 0xFF, 0xFF, 0x78
|
||||
};
|
95
kernel/asm/ARStartDMA.S
Normal file
95
kernel/asm/ARStartDMA.S
Normal file
@@ -0,0 +1,95 @@
|
||||
#include <asm.h>
|
||||
|
||||
#in
|
||||
# r3 u32 type
|
||||
# r4 u32 mainmem_addr
|
||||
# r5 u32 aram_addr
|
||||
# r6 u32 length
|
||||
|
||||
#out
|
||||
# none
|
||||
|
||||
ARStartDMA:
|
||||
stwu %sp, -0x10(%sp)
|
||||
mflr %r0
|
||||
stw %r0, 8(%sp)
|
||||
|
||||
lis %r7, 0x0FFF
|
||||
ori %r7, %r7, 0xFFFF
|
||||
|
||||
and %r5, %r5, %r7
|
||||
addis %r5, %r5, 0xD000 # mem2
|
||||
|
||||
cmpwi %r3, 1
|
||||
beq ARAM_TO_MRAM
|
||||
bne MRAM_TO_ARAM
|
||||
|
||||
memcpy_pre:
|
||||
mr %r7, %r6 #save length
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r4)
|
||||
stwu %r0, 4(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
bne memcpy
|
||||
|
||||
cmpwi %r3, 1
|
||||
bne end
|
||||
|
||||
addi %r5, %r5, 4
|
||||
sub %r5, %r5, %r7
|
||||
srwi %r7, %r7, 5
|
||||
mtctr %r7
|
||||
|
||||
li %r0, 0
|
||||
DCFlushRange:
|
||||
dcbf %r0, %r5
|
||||
addi %r5, %r5, 0x20
|
||||
bdnz DCFlushRange
|
||||
|
||||
end:
|
||||
|
||||
#Fake IRQ
|
||||
|
||||
# lis %r3, 0xC000
|
||||
|
||||
# li %r0, 0x20
|
||||
# stw %r0, 0x0054(%r3)
|
||||
|
||||
# li %r0, 0x40
|
||||
# stw %r0, 0x0050(%r3)
|
||||
|
||||
#ARAM Transfer Fake
|
||||
|
||||
lis %r3, 0xCC00
|
||||
stw %r6, 0x5028(%r3)
|
||||
|
||||
lwz %r0, 8(%sp)
|
||||
mtlr %r0
|
||||
addi %sp, %sp, 0x10
|
||||
|
||||
blr
|
||||
|
||||
ARAM_TO_MRAM:
|
||||
mr %r7, %r5
|
||||
mr %r5, %r4
|
||||
mr %r4, %r7
|
||||
|
||||
b memcpy_pre
|
||||
|
||||
MRAM_TO_ARAM:
|
||||
|
||||
srwi %r7, %r6, 5
|
||||
mtctr %r7
|
||||
mr %r7, %r4
|
||||
|
||||
li %r0, 0
|
||||
DCInvalidateRange:
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
bdnz DCInvalidateRange
|
||||
|
||||
b memcpy_pre
|
22
kernel/asm/ARStartDMA.h
Normal file
22
kernel/asm/ARStartDMA.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Filename : ARStartDMA.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define ARStartDMA_size 0xb8
|
||||
|
||||
const unsigned char ARStartDMA[] = {
|
||||
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x08, 0x3C, 0xE0, 0x0F, 0xFF,
|
||||
0x60, 0xE7, 0xFF, 0xFF, 0x7C, 0xA5, 0x38, 0x38, 0x3C, 0xA5, 0xD0, 0x00, 0x2C, 0x03, 0x00, 0x01,
|
||||
0x41, 0x82, 0x00, 0x68, 0x40, 0x82, 0x00, 0x74, 0x7C, 0xC7, 0x33, 0x78, 0x80, 0x04, 0x00, 0x00,
|
||||
0x90, 0x05, 0x00, 0x00, 0x34, 0xC6, 0xFF, 0xFC, 0x84, 0x04, 0x00, 0x04, 0x94, 0x05, 0x00, 0x04,
|
||||
0x34, 0xC6, 0xFF, 0xFC, 0x40, 0x82, 0xFF, 0xF4, 0x2C, 0x03, 0x00, 0x01, 0x40, 0x82, 0x00, 0x24,
|
||||
0x38, 0xA5, 0x00, 0x04, 0x7C, 0xA7, 0x28, 0x50, 0x54, 0xE7, 0xD9, 0x7E, 0x7C, 0xE9, 0x03, 0xA6,
|
||||
0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x28, 0xAC, 0x38, 0xA5, 0x00, 0x20, 0x42, 0x00, 0xFF, 0xF8,
|
||||
0x3C, 0x60, 0xCC, 0x00, 0x90, 0xC3, 0x50, 0x28, 0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6,
|
||||
0x38, 0x21, 0x00, 0x10, 0x4E, 0x80, 0x00, 0x20, 0x7C, 0xA7, 0x2B, 0x78, 0x7C, 0x85, 0x23, 0x78,
|
||||
0x7C, 0xE4, 0x3B, 0x78, 0x4B, 0xFF, 0xFF, 0x94, 0x54, 0xC7, 0xD9, 0x7E, 0x7C, 0xE9, 0x03, 0xA6,
|
||||
0x7C, 0x87, 0x23, 0x78, 0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x3B, 0xAC, 0x38, 0xE7, 0x00, 0x20,
|
||||
0x42, 0x00, 0xFF, 0xF8, 0x4B, 0xFF, 0xFF, 0x74
|
||||
};
|
7
kernel/asm/AXSetVoiceAdr.S
Normal file
7
kernel/asm/AXSetVoiceAdr.S
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <asm.h>
|
||||
|
||||
|
||||
AXSetVoiceAdr:
|
||||
|
||||
oris %r31, %r4, 0x2000
|
||||
blr
|
11
kernel/asm/AXSetVoiceAdr.h
Normal file
11
kernel/asm/AXSetVoiceAdr.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
Filename : AXSetVoiceAdr.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define AXSetVoiceAdr_size 0x8
|
||||
|
||||
const unsigned char AXSetVoiceAdr[] = {
|
||||
|
||||
0x64, 0x9F, 0x20, 0x00, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
20
kernel/asm/AXSetVoiceState.S
Normal file
20
kernel/asm/AXSetVoiceState.S
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <asm.h>
|
||||
|
||||
|
||||
AXSetVoiceState:
|
||||
|
||||
lwz %r3, 0x1AA(%r30)
|
||||
oris %r3, %r3, 0x2000
|
||||
stw %r3, 0x1AA(%r30)
|
||||
|
||||
lwz %r3, 0x1AE(%r30)
|
||||
oris %r3, %r3, 0x2000
|
||||
stw %r3, 0x1AE(%r30)
|
||||
|
||||
lwz %r3, 0x1B2(%r30)
|
||||
oris %r3, %r3, 0x2000
|
||||
stw %r3, 0x1B2(%r30)
|
||||
|
||||
stw %r0, 0x1C(%r30)
|
||||
|
||||
blr
|
13
kernel/asm/AXSetVoiceState.h
Normal file
13
kernel/asm/AXSetVoiceState.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Filename : AXSetVoiceState.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define AXSetVoiceState_size 0x2c
|
||||
|
||||
const unsigned char AXSetVoiceState[] = {
|
||||
|
||||
0x80, 0x7E, 0x01, 0xAA, 0x64, 0x63, 0x20, 0x00, 0x90, 0x7E, 0x01, 0xAA, 0x80, 0x7E, 0x01, 0xAE,
|
||||
0x64, 0x63, 0x20, 0x00, 0x90, 0x7E, 0x01, 0xAE, 0x80, 0x7E, 0x01, 0xB2, 0x64, 0x63, 0x20, 0x00,
|
||||
0x90, 0x7E, 0x01, 0xB2, 0x90, 0x1E, 0x00, 0x1C, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
23
kernel/asm/CARDCheck.S
Normal file
23
kernel/asm/CARDCheck.S
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDCheck:
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
li %r3, 0
|
||||
end:
|
||||
|
||||
lis %r4, 0xC000
|
||||
stw %r3, 0x2F94(%r4)
|
||||
|
||||
mtlr %r0
|
||||
blr
|
13
kernel/asm/CARDCheck.h
Normal file
13
kernel/asm/CARDCheck.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Filename : CARDCheck.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDCheck_size 0x28
|
||||
|
||||
const unsigned char CARDCheck[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD,
|
||||
0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0x00, 0x00, 0x3C, 0x80, 0xC0, 0x00, 0x90, 0x64, 0x2F, 0x94,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
43
kernel/asm/CARDCheckAsync.S
Normal file
43
kernel/asm/CARDCheckAsync.S
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 cb( chan, res )
|
||||
|
||||
CARDCheck:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq NoCardNoCB
|
||||
|
||||
mtctr %r4
|
||||
li %r4, -3
|
||||
bctrl
|
||||
|
||||
NoCardNoCB:
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq CardNoCB
|
||||
|
||||
mtctr %r4
|
||||
li %r4, 0
|
||||
bctrl
|
||||
|
||||
CardNoCB:
|
||||
li %r3, 0
|
||||
end:
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
||||
|
16
kernel/asm/CARDCheckAsync.h
Normal file
16
kernel/asm/CARDCheckAsync.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
Filename : CARDCheckAsync.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDCheckAsync_size 0x58
|
||||
|
||||
const unsigned char CARDCheckAsync[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x2C, 0x03, 0x00, 0x00,
|
||||
0x41, 0x82, 0x00, 0x20, 0x2C, 0x04, 0x00, 0x00, 0x41, 0x82, 0x00, 0x10, 0x7C, 0x89, 0x03, 0xA6,
|
||||
0x38, 0x80, 0xFF, 0xFD, 0x4E, 0x80, 0x04, 0x21, 0x38, 0x60, 0xFF, 0xFD, 0x48, 0x00, 0x00, 0x1C,
|
||||
0x2C, 0x04, 0x00, 0x00, 0x41, 0x82, 0x00, 0x10, 0x7C, 0x89, 0x03, 0xA6, 0x38, 0x80, 0x00, 0x00,
|
||||
0x4E, 0x80, 0x04, 0x21, 0x38, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
60
kernel/asm/CARDCheckEX.S
Normal file
60
kernel/asm/CARDCheckEX.S
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 *xfer bytes used to repair the FS
|
||||
# r5 cb
|
||||
|
||||
CARDCheckEx:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq NoCardZeroPtr
|
||||
|
||||
li %r6, 0
|
||||
stw %r6, 0(%r4)
|
||||
|
||||
NoCardZeroPtr:
|
||||
cmpwi %r5, 0
|
||||
beq NoCardNoCB
|
||||
|
||||
mtctr %r5
|
||||
li %r4, -3
|
||||
bctrl
|
||||
|
||||
NoCardNoCB:
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq CardZeroPtr
|
||||
|
||||
li %r6, 0
|
||||
stw %r6, 0(%r4)
|
||||
|
||||
CardZeroPtr:
|
||||
cmpwi %r5, 0
|
||||
beq CardNoCB
|
||||
|
||||
mtctr %r5
|
||||
li %r4, 0
|
||||
bctrl
|
||||
|
||||
CardNoCB:
|
||||
li %r3, 0
|
||||
end:
|
||||
lis %r4, 0xC000
|
||||
stw %r3, 0x2F94(%r4)
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
19
kernel/asm/CARDCheckEX.h
Normal file
19
kernel/asm/CARDCheckEX.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Filename : CARDCheckEX.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDCheckEX_size 0x80
|
||||
|
||||
const unsigned char CARDCheckEX[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x2C, 0x03, 0x00, 0x00,
|
||||
0x41, 0x82, 0x00, 0x30, 0x2C, 0x04, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0xC0, 0x00, 0x00,
|
||||
0x90, 0xC4, 0x00, 0x00, 0x2C, 0x05, 0x00, 0x00, 0x41, 0x82, 0x00, 0x10, 0x7C, 0xA9, 0x03, 0xA6,
|
||||
0x38, 0x80, 0xFF, 0xFD, 0x4E, 0x80, 0x04, 0x21, 0x38, 0x60, 0xFF, 0xFD, 0x48, 0x00, 0x00, 0x2C,
|
||||
0x2C, 0x04, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0xC0, 0x00, 0x00, 0x90, 0xC4, 0x00, 0x00,
|
||||
0x2C, 0x05, 0x00, 0x00, 0x41, 0x82, 0x00, 0x10, 0x7C, 0xA9, 0x03, 0xA6, 0x38, 0x80, 0x00, 0x00,
|
||||
0x4E, 0x80, 0x04, 0x21, 0x38, 0x60, 0x00, 0x00, 0x3C, 0x80, 0xC0, 0x00, 0x90, 0x64, 0x2F, 0x94,
|
||||
0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
47
kernel/asm/CARDClose.S
Normal file
47
kernel/asm/CARDClose.S
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 FileInfo
|
||||
|
||||
CARDClose:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC100
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
lwz %r0, 0x04(%r3)
|
||||
stw %r0, 0x2F64(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
17
kernel/asm/CARDClose.h
Normal file
17
kernel/asm/CARDClose.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Filename : CARDClose.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDClose_size 0x6c
|
||||
|
||||
const unsigned char CARDClose[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x38, 0x00, 0x00, 0x00,
|
||||
0x3C, 0xE0, 0xC0, 0x00, 0x38, 0xE7, 0x2F, 0x60, 0x7C, 0x00, 0x3B, 0xAC, 0x3C, 0xE0, 0xC0, 0x00,
|
||||
0x3C, 0x00, 0xC1, 0x00, 0x90, 0x07, 0x2F, 0x60, 0x80, 0x03, 0x00, 0x04, 0x90, 0x07, 0x2F, 0x64,
|
||||
0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78, 0x80, 0x07, 0x2F, 0x78, 0x2C, 0x00, 0x00, 0x03,
|
||||
0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C, 0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00,
|
||||
0x41, 0x82, 0xFF, 0xF4, 0x80, 0x67, 0x2F, 0x94, 0x7C, 0x64, 0x1B, 0x78, 0x80, 0x01, 0x00, 0x14,
|
||||
0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
85
kernel/asm/CARDCreate.S
Normal file
85
kernel/asm/CARDCreate.S
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 fileName
|
||||
# r5 size
|
||||
# r6 fileInfo
|
||||
# r7 cb
|
||||
|
||||
CARDCreate:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
li %r4, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x28(%sp)
|
||||
stmw %r27, 0x14(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC200
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
stw %r6, 0x2F6C(%r7)
|
||||
|
||||
memcpy_pre:
|
||||
li %r6, 8
|
||||
lis %r5, 0xD201
|
||||
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r4)
|
||||
stwu %r0, 4(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
bne memcpy
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r0, 0x2F90(%r7)
|
||||
stw %r0, 0x04(%r6)
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lis %r7, 0xC000
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lmw %r27, 0x14(%sp)
|
||||
lwz %r0, 0x2C(%sp)
|
||||
addi %sp, %sp, 0x28
|
||||
mtlr %r0
|
||||
blr
|
||||
|
23
kernel/asm/CARDCreate.h
Normal file
23
kernel/asm/CARDCreate.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Filename : CARDCreate.bin
|
||||
Date created: Sat Apr 19 02:21:58 2014
|
||||
*/
|
||||
|
||||
#define CARDCreate_size 0xc8
|
||||
|
||||
const unsigned char CARDCreate[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x10, 0x38, 0x60, 0xFF, 0xFD, 0x38, 0x80, 0xFF, 0xFD,
|
||||
0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xD8,
|
||||
0xBF, 0x61, 0x00, 0x14, 0x7C, 0xEC, 0x3B, 0x78, 0x3C, 0xE0, 0xC0, 0x00, 0x3C, 0x00, 0xC2, 0x00,
|
||||
0x90, 0x07, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64, 0x90, 0xA7, 0x2F, 0x68, 0x90, 0xC7, 0x2F, 0x6C,
|
||||
0x38, 0xC0, 0x00, 0x08, 0x3C, 0xA0, 0xD2, 0x01, 0x80, 0x04, 0x00, 0x00, 0x90, 0x05, 0x00, 0x00,
|
||||
0x34, 0xC6, 0xFF, 0xFC, 0x84, 0x04, 0x00, 0x04, 0x94, 0x05, 0x00, 0x04, 0x34, 0xC6, 0xFF, 0xFC,
|
||||
0x40, 0x82, 0xFF, 0xF4, 0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78, 0x80, 0x07, 0x2F, 0x78,
|
||||
0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C, 0x70, 0x00, 0x00, 0x14,
|
||||
0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4, 0x80, 0x07, 0x2F, 0x90, 0x90, 0x06, 0x00, 0x04,
|
||||
0x2C, 0x0C, 0x00, 0x00, 0x41, 0x82, 0x00, 0x14, 0x7D, 0x88, 0x03, 0xA6, 0x38, 0x60, 0x00, 0x00,
|
||||
0x38, 0x80, 0x00, 0x00, 0x4E, 0x80, 0x00, 0x21, 0x3C, 0xE0, 0xC0, 0x00, 0x80, 0x67, 0x2F, 0x94,
|
||||
0x7C, 0x64, 0x1B, 0x78, 0xBB, 0x61, 0x00, 0x14, 0x80, 0x01, 0x00, 0x2C, 0x38, 0x21, 0x00, 0x28,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
80
kernel/asm/CARDDelete.S
Normal file
80
kernel/asm/CARDDelete.S
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 fileName
|
||||
# r5 cb
|
||||
|
||||
CARDDelete:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r5
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC600
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
|
||||
#cache workaround for the filename
|
||||
li %r5, 8
|
||||
mtctr %r5
|
||||
lis %r5, 0xC000
|
||||
invalidloop:
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0x17E0(%r5)
|
||||
addi %r4, %r4, 4
|
||||
addi %r5, %r5, 4
|
||||
bdnz invalidloop
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lis %r7, 0xC000
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
||||
|
23
kernel/asm/CARDDelete.h
Normal file
23
kernel/asm/CARDDelete.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Filename : CARDDelete.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDDelete_size 0xc0
|
||||
|
||||
const unsigned char CARDDelete[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD, 0x4E, 0x80, 0x00, 0x20,
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x7C, 0xAC, 0x2B, 0x78,
|
||||
0x38, 0x00, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x00, 0x38, 0xE7, 0x2F, 0x60, 0x7C, 0x00, 0x3B, 0xAC,
|
||||
0x38, 0xE7, 0x00, 0x20, 0x7C, 0x00, 0x3B, 0xAC, 0x3C, 0xE0, 0xC0, 0x00, 0x3C, 0x00, 0xC6, 0x00,
|
||||
0x90, 0x07, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64, 0x38, 0xA0, 0x00, 0x08, 0x7C, 0xA9, 0x03, 0xA6,
|
||||
0x3C, 0xA0, 0xC0, 0x00, 0x80, 0x04, 0x00, 0x00, 0x90, 0x05, 0x17, 0xE0, 0x38, 0x84, 0x00, 0x04,
|
||||
0x38, 0xA5, 0x00, 0x04, 0x42, 0x00, 0xFF, 0xF0, 0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78,
|
||||
0x80, 0x07, 0x2F, 0x78, 0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C,
|
||||
0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4, 0x2C, 0x0C, 0x00, 0x00,
|
||||
0x41, 0x82, 0x00, 0x14, 0x7D, 0x88, 0x03, 0xA6, 0x80, 0x67, 0x2F, 0x94, 0x38, 0x80, 0x00, 0x00,
|
||||
0x4E, 0x80, 0x00, 0x21, 0x3C, 0xE0, 0xC0, 0x00, 0x80, 0x67, 0x2F, 0x94, 0x7C, 0x64, 0x1B, 0x78,
|
||||
0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
69
kernel/asm/CARDFastDelete.S
Normal file
69
kernel/asm/CARDFastDelete.S
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileNo
|
||||
# r5 cb
|
||||
|
||||
CARDFastDelete:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r5
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xCA00
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lis %r7, 0xC000
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
||||
|
21
kernel/asm/CARDFastDelete.h
Normal file
21
kernel/asm/CARDFastDelete.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Filename : CARDFastDelete.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDFastDelete_size 0xa0
|
||||
|
||||
const unsigned char CARDFastDelete[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD, 0x4E, 0x80, 0x00, 0x20,
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x7C, 0xAC, 0x2B, 0x78,
|
||||
0x38, 0x00, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x00, 0x38, 0xE7, 0x2F, 0x60, 0x7C, 0x00, 0x3B, 0xAC,
|
||||
0x38, 0xE7, 0x00, 0x20, 0x7C, 0x00, 0x3B, 0xAC, 0x3C, 0xE0, 0xC0, 0x00, 0x3C, 0x00, 0xCA, 0x00,
|
||||
0x90, 0x07, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64, 0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78,
|
||||
0x80, 0x07, 0x2F, 0x78, 0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C,
|
||||
0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4, 0x2C, 0x0C, 0x00, 0x00,
|
||||
0x41, 0x82, 0x00, 0x14, 0x7D, 0x88, 0x03, 0xA6, 0x80, 0x67, 0x2F, 0x94, 0x38, 0x80, 0x00, 0x00,
|
||||
0x4E, 0x80, 0x00, 0x21, 0x3C, 0xE0, 0xC0, 0x00, 0x80, 0x67, 0x2F, 0x94, 0x7C, 0x64, 0x1B, 0x78,
|
||||
0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
62
kernel/asm/CARDFastOpen.S
Normal file
62
kernel/asm/CARDFastOpen.S
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileNo
|
||||
# r5 FileInfo
|
||||
|
||||
CARDFastOpen:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
bne NoCard
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC500
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r3, 0x2F90(%r7)
|
||||
stw %r3, 0x10(%r5)
|
||||
stw %r4, 0x04(%r5)
|
||||
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
b end
|
||||
|
||||
NoCard:
|
||||
li %r3, -3
|
||||
end:
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
19
kernel/asm/CARDFastOpen.h
Normal file
19
kernel/asm/CARDFastOpen.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Filename : CARDFastOpen.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDFastOpen_size 0x8c
|
||||
|
||||
const unsigned char CARDFastOpen[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x2C, 0x03, 0x00, 0x00,
|
||||
0x40, 0x82, 0x00, 0x68, 0x38, 0x00, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x00, 0x38, 0xE7, 0x2F, 0x60,
|
||||
0x7C, 0x00, 0x3B, 0xAC, 0x38, 0xE7, 0x00, 0x20, 0x7C, 0x00, 0x3B, 0xAC, 0x3C, 0xE0, 0xC0, 0x00,
|
||||
0x3C, 0x00, 0xC5, 0x00, 0x90, 0x07, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64, 0x90, 0xA7, 0x2F, 0x68,
|
||||
0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78, 0x80, 0x07, 0x2F, 0x78, 0x2C, 0x00, 0x00, 0x03,
|
||||
0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C, 0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00,
|
||||
0x41, 0x82, 0xFF, 0xF4, 0x80, 0x67, 0x2F, 0x90, 0x90, 0x65, 0x00, 0x10, 0x90, 0x85, 0x00, 0x04,
|
||||
0x80, 0x67, 0x2F, 0x94, 0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0xFF, 0xFD, 0x80, 0x01, 0x00, 0x14,
|
||||
0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
32
kernel/asm/CARDFreeBlocks.S
Normal file
32
kernel/asm/CARDFreeBlocks.S
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 byteNotUsed
|
||||
# r5 filesNotUsed
|
||||
|
||||
CARDFreeBlocks:
|
||||
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
lis %r3, 0x7F
|
||||
addi %r3, %r3, 0x6000
|
||||
stw %r3, 0(%r4)
|
||||
|
||||
li %r3, 16
|
||||
stw %r3, 0(%r5)
|
||||
|
||||
li %r3, 0
|
||||
|
||||
end:
|
||||
|
||||
mtlr %r0
|
||||
blr
|
14
kernel/asm/CARDFreeBlocks.h
Normal file
14
kernel/asm/CARDFreeBlocks.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Filename : CARDFreeBlocks.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDFreeBlocks_size 0x34
|
||||
|
||||
const unsigned char CARDFreeBlocks[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD,
|
||||
0x48, 0x00, 0x00, 0x1C, 0x3C, 0x60, 0x00, 0x7F, 0x38, 0x63, 0x60, 0x00, 0x90, 0x64, 0x00, 0x00,
|
||||
0x38, 0x60, 0x00, 0x10, 0x90, 0x65, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x7C, 0x08, 0x03, 0xA6,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
30
kernel/asm/CARDGetEncoding.S
Normal file
30
kernel/asm/CARDGetEncoding.S
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 endcoding(u16)
|
||||
|
||||
CARDGetEncoding:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#0 is USA/EUR, 1 is JAP
|
||||
li %r0, 0
|
||||
sth %r0, 0(%r4)
|
||||
|
||||
end:
|
||||
li %r3, 0
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
14
kernel/asm/CARDGetEncoding.h
Normal file
14
kernel/asm/CARDGetEncoding.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Filename : CARDGetEncoding.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDGetEncoding_size 0x38
|
||||
|
||||
const unsigned char CARDGetEncoding[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD, 0x4E, 0x80, 0x00, 0x20,
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x38, 0x00, 0x00, 0x00,
|
||||
0xB0, 0x04, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
30
kernel/asm/CARDGetMemSize.S
Normal file
30
kernel/asm/CARDGetMemSize.S
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 size(u16)
|
||||
|
||||
CARDGetMemSize:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#possible sizes 4,8,16,32,64,128
|
||||
li %r0, 8
|
||||
sth %r0, 0(%r4)
|
||||
|
||||
end:
|
||||
li %r3, 0
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
14
kernel/asm/CARDGetMemSize.h
Normal file
14
kernel/asm/CARDGetMemSize.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Filename : CARDGetMemSize.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDGetMemSize_size 0x38
|
||||
|
||||
const unsigned char CARDGetMemSize[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD, 0x4E, 0x80, 0x00, 0x20,
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x38, 0x00, 0x00, 0x08,
|
||||
0xB0, 0x04, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
19
kernel/asm/CARDGetResultCode.S
Normal file
19
kernel/asm/CARDGetResultCode.S
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDGetResultCode:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
lis %r3, 0xC000
|
||||
lwz %r3, 0x2F94(%r3)
|
||||
end:
|
||||
|
||||
blr
|
12
kernel/asm/CARDGetResultCode.h
Normal file
12
kernel/asm/CARDGetResultCode.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Filename : CARDGetResultCode.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDGetResultCode_size 0x1c
|
||||
|
||||
const unsigned char CARDGetResultCode[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD, 0x48, 0x00, 0x00, 0x0C,
|
||||
0x3C, 0x60, 0xC0, 0x00, 0x80, 0x63, 0x2F, 0x94, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
29
kernel/asm/CARDGetSerialNo.S
Normal file
29
kernel/asm/CARDGetSerialNo.S
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 serialNo
|
||||
|
||||
CARDGetSerialNo:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
|
||||
lis %r3, 0xc7bd
|
||||
subi %r3, %r3, 0x26C
|
||||
stw %r3, 0x00(%r4)
|
||||
|
||||
lis %r3, 0xf47f
|
||||
subi %r3, %r3, 0x3924
|
||||
stw %r3, 0x04(%r4)
|
||||
|
||||
li %r3, 0
|
||||
|
||||
mtlr %r0
|
||||
blr
|
14
kernel/asm/CARDGetSerialNo.h
Normal file
14
kernel/asm/CARDGetSerialNo.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Filename : CARDGetSerialNo.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDGetSerialNo_size 0x38
|
||||
|
||||
const unsigned char CARDGetSerialNo[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD, 0x4E, 0x80, 0x00, 0x20,
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x3C, 0x60, 0xC7, 0xBD, 0x38, 0x63, 0xFD, 0x94, 0x90, 0x64, 0x00, 0x00,
|
||||
0x3C, 0x60, 0xF4, 0x7F, 0x38, 0x63, 0xC6, 0xDC, 0x90, 0x64, 0x00, 0x04, 0x38, 0x60, 0x00, 0x00,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
66
kernel/asm/CARDGetStats.S
Normal file
66
kernel/asm/CARDGetStats.S
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileNo
|
||||
# r5 Stat
|
||||
# r6 cb
|
||||
|
||||
CARDGetStats:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, 0
|
||||
li %r4, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to nintendont
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC300
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
memcpy_pre:
|
||||
li %r6, 0x6C
|
||||
lis %r4, 0xD201
|
||||
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r4)
|
||||
stwu %r0, 4(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
bne memcpy
|
||||
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
20
kernel/asm/CARDGetStats.h
Normal file
20
kernel/asm/CARDGetStats.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Filename : CARDGetStats.bin
|
||||
Date created: Sat Apr 19 02:21:58 2014
|
||||
*/
|
||||
|
||||
#define CARDGetStats_size 0x94
|
||||
|
||||
const unsigned char CARDGetStats[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x10, 0x38, 0x60, 0x00, 0x00, 0x38, 0x80, 0xFF, 0xFD,
|
||||
0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0,
|
||||
0x3C, 0xE0, 0xC0, 0x00, 0x3C, 0x00, 0xC3, 0x00, 0x90, 0x07, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64,
|
||||
0x90, 0xA7, 0x2F, 0x68, 0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78, 0x80, 0x07, 0x2F, 0x78,
|
||||
0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C, 0x70, 0x00, 0x00, 0x14,
|
||||
0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4, 0x38, 0xC0, 0x00, 0x6C, 0x3C, 0x80, 0xD2, 0x01,
|
||||
0x80, 0x04, 0x00, 0x00, 0x90, 0x05, 0x00, 0x00, 0x34, 0xC6, 0xFF, 0xFC, 0x84, 0x04, 0x00, 0x04,
|
||||
0x94, 0x05, 0x00, 0x04, 0x34, 0xC6, 0xFF, 0xFC, 0x40, 0x82, 0xFF, 0xF4, 0x80, 0x67, 0x2F, 0x94,
|
||||
0x7C, 0x64, 0x1B, 0x78, 0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
17
kernel/asm/CARDGetXferredBytes.S
Normal file
17
kernel/asm/CARDGetXferredBytes.S
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDGetEncoding:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
lis %r3, 0xC000
|
||||
lwz %r3, 0x2FA0(%r3)
|
||||
|
||||
blr
|
12
kernel/asm/CARDGetXferredBytes.h
Normal file
12
kernel/asm/CARDGetXferredBytes.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Filename : CARDGetXferredBytes.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDGetXferredBytes_size 0x18
|
||||
|
||||
const unsigned char CARDGetXferredBytes[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x08, 0x4E, 0x80, 0x00, 0x20, 0x3C, 0x60, 0xC0, 0x00,
|
||||
0x80, 0x63, 0x2F, 0xA0, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
26
kernel/asm/CARDMount.S
Normal file
26
kernel/asm/CARDMount.S
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 workarea
|
||||
# r5 detachCallback
|
||||
|
||||
CARDMount:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
li %r3, 0
|
||||
end:
|
||||
|
||||
lwz %r0, 4(%sp)
|
||||
mtlr %r0
|
||||
blr
|
13
kernel/asm/CARDMount.h
Normal file
13
kernel/asm/CARDMount.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Filename : CARDMount.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDMount_size 0x28
|
||||
|
||||
const unsigned char CARDMount[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C,
|
||||
0x38, 0x60, 0xFF, 0xFD, 0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x04,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
46
kernel/asm/CARDMountAsync.S
Normal file
46
kernel/asm/CARDMountAsync.S
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 workarea
|
||||
# r5 detachCallback
|
||||
# r6 attachCallback
|
||||
|
||||
CARDMountAsync:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
lis %r7, 0xC000
|
||||
stw %r3, 0x2F94(%r7)
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
|
||||
cmpwi %r6, 0
|
||||
beq end
|
||||
|
||||
mtctr %r6
|
||||
bctrl
|
||||
|
||||
lis %r7, 0xC000
|
||||
li %r3, 4
|
||||
stw %r3, 0x2F9C(%r7)
|
||||
|
||||
end:
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
lis %r7, 0xC000
|
||||
stw %r3, 0x2F94(%r7)
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
17
kernel/asm/CARDMountAsync.h
Normal file
17
kernel/asm/CARDMountAsync.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Filename : CARDMountAsync.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDMountAsync_size 0x68
|
||||
|
||||
const unsigned char CARDMountAsync[] = {
|
||||
|
||||
0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x14, 0x38, 0x60, 0xFF, 0xFD, 0x3C, 0xE0, 0xC0, 0x00,
|
||||
0x90, 0x67, 0x2F, 0x94, 0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04,
|
||||
0x94, 0x21, 0xFF, 0xF0, 0x38, 0x60, 0x00, 0x00, 0x38, 0x80, 0x00, 0x00, 0x2C, 0x06, 0x00, 0x00,
|
||||
0x41, 0x82, 0x00, 0x18, 0x7C, 0xC9, 0x03, 0xA6, 0x4E, 0x80, 0x04, 0x21, 0x3C, 0xE0, 0xC0, 0x00,
|
||||
0x38, 0x60, 0x00, 0x04, 0x90, 0x67, 0x2F, 0x9C, 0x38, 0x60, 0x00, 0x00, 0x38, 0x80, 0x00, 0x00,
|
||||
0x3C, 0xE0, 0xC0, 0x00, 0x90, 0x67, 0x2F, 0x94, 0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10,
|
||||
0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
};
|
66
kernel/asm/CARDOpen.S
Normal file
66
kernel/asm/CARDOpen.S
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileName
|
||||
# r5 FileInfo
|
||||
|
||||
CARDOpen:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
bne NoCard
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
lis %r7, 0xC000
|
||||
#cmd is the same as the offset, one opcode saved!
|
||||
stw %r7, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
memcpy_pre:
|
||||
li %r6, 8
|
||||
lis %r5, 0xD201
|
||||
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r4)
|
||||
stwu %r0, 4(%r5)
|
||||
addic. %r6, %r6, -4
|
||||
bne memcpy
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r0, 0x2F90(%r7)
|
||||
stw %r0, 0x04(%r5)
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
b end
|
||||
|
||||
NoCard:
|
||||
li %r3, -3
|
||||
end:
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
20
kernel/asm/CARDOpen.h
Normal file
20
kernel/asm/CARDOpen.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Filename : CARDOpen.bin
|
||||
Date created: Sat Apr 19 02:21:58 2014
|
||||
*/
|
||||
|
||||
#define CARDOpen_size 0x94
|
||||
|
||||
const unsigned char CARDOpen[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xF0, 0x2C, 0x03, 0x00, 0x00,
|
||||
0x40, 0x82, 0x00, 0x6C, 0x3C, 0xE0, 0xC0, 0x00, 0x90, 0xE7, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64,
|
||||
0x90, 0xA7, 0x2F, 0x68, 0x38, 0xC0, 0x00, 0x08, 0x3C, 0xA0, 0xD2, 0x01, 0x80, 0x04, 0x00, 0x00,
|
||||
0x90, 0x05, 0x00, 0x00, 0x34, 0xC6, 0xFF, 0xFC, 0x84, 0x04, 0x00, 0x04, 0x94, 0x05, 0x00, 0x04,
|
||||
0x34, 0xC6, 0xFF, 0xFC, 0x40, 0x82, 0xFF, 0xF4, 0x38, 0x00, 0x00, 0x03, 0x90, 0x07, 0x2F, 0x78,
|
||||
0x80, 0x07, 0x2F, 0x78, 0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8, 0x80, 0x07, 0x2F, 0x9C,
|
||||
0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4, 0x80, 0x07, 0x2F, 0x90,
|
||||
0x90, 0x05, 0x00, 0x04, 0x80, 0x67, 0x2F, 0x94, 0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0xFF, 0xFD,
|
||||
0x7C, 0x64, 0x1B, 0x78, 0x80, 0x01, 0x00, 0x14, 0x38, 0x21, 0x00, 0x10, 0x7C, 0x08, 0x03, 0xA6,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
21
kernel/asm/CARDProbe.S
Normal file
21
kernel/asm/CARDProbe.S
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDProbe:
|
||||
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, 0
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
li %r3, 1
|
||||
end:
|
||||
|
||||
mtlr %r0
|
||||
blr
|
13
kernel/asm/CARDProbe.h
Normal file
13
kernel/asm/CARDProbe.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Filename : CARDProbe.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDProbe_size 0x20
|
||||
|
||||
const unsigned char CARDProbe[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x00,
|
||||
0x48, 0x00, 0x00, 0x08, 0x38, 0x60, 0x00, 0x01, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
41
kernel/asm/CARDProbeEX.S
Normal file
41
kernel/asm/CARDProbeEX.S
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 MemSize (can be zero ptr)
|
||||
# r5 SecSize (can be zero ptr)
|
||||
|
||||
CARDProbeEX:
|
||||
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq ZeroMemPtr
|
||||
|
||||
li %r3, 8
|
||||
stw %r3, 0(%r4)
|
||||
|
||||
ZeroMemPtr:
|
||||
|
||||
cmpwi %r5, 0
|
||||
beq ZeroSecPtr
|
||||
|
||||
li %r3, 0x2000
|
||||
stw %r3, 0(%r5)
|
||||
|
||||
ZeroSecPtr:
|
||||
|
||||
li %r3, 0
|
||||
|
||||
end:
|
||||
|
||||
mtlr %r0
|
||||
blr
|
15
kernel/asm/CARDProbeEX.h
Normal file
15
kernel/asm/CARDProbeEX.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
Filename : CARDProbeEX.bin
|
||||
Date created: Sat Sep 28 10:11:43 2013
|
||||
*/
|
||||
|
||||
#define CARDProbeEX_size 0x40
|
||||
|
||||
const unsigned char CARDProbeEX[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0xFF, 0xFD,
|
||||
0x48, 0x00, 0x00, 0x28, 0x2C, 0x04, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x08,
|
||||
0x90, 0x64, 0x00, 0x00, 0x2C, 0x05, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x20, 0x00,
|
||||
0x90, 0x65, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x7C, 0x08, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20
|
||||
|
||||
};
|
80
kernel/asm/CARDRead.S
Normal file
80
kernel/asm/CARDRead.S
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 file *
|
||||
# r4 buffer
|
||||
# r5 length
|
||||
# r6 offset
|
||||
# r7 cb
|
||||
|
||||
CardRead:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x28(%sp)
|
||||
stmw %r27, 0x14(%sp)
|
||||
|
||||
#Update fileinfo
|
||||
stw %r5, 0x0C(%r3)
|
||||
stw %r6, 0x08(%r3)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC900
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
stw %r6, 0x2F6C(%r7)
|
||||
|
||||
lwz %r0, 0x04(%r3)
|
||||
stw %r0, 0x2F70(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
memcpy_pre:
|
||||
lis %r6, 0xD201
|
||||
|
||||
lwz %r0, 0(%r6)
|
||||
stw %r0, 0(%r4)
|
||||
addic. %r5, %r5, -4
|
||||
|
||||
memcpy:
|
||||
lwzu %r0, 4(%r6)
|
||||
stwu %r0, 4(%r4)
|
||||
addic. %r5, %r5, -4
|
||||
bne memcpy
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
li %r3, 0
|
||||
mr %r4, %r3
|
||||
|
||||
lmw %r27, 0x14(%sp)
|
||||
lwz %r0, 0x2C(%sp)
|
||||
addi %sp, %sp, 0x28
|
||||
mtlr %r0
|
||||
blr
|
22
kernel/asm/CARDRead.h
Normal file
22
kernel/asm/CARDRead.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Filename : CARDRead.bin
|
||||
Date created: Sat Apr 19 02:21:58 2014
|
||||
*/
|
||||
|
||||
#define CARDRead_size 0xb4
|
||||
|
||||
const unsigned char CARDRead[] = {
|
||||
|
||||
0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xD8, 0xBF, 0x61, 0x00, 0x14,
|
||||
0x90, 0xA3, 0x00, 0x0C, 0x90, 0xC3, 0x00, 0x08, 0x7C, 0xEC, 0x3B, 0x78, 0x3C, 0xE0, 0xC0, 0x00,
|
||||
0x3C, 0x00, 0xC9, 0x00, 0x90, 0x07, 0x2F, 0x60, 0x90, 0x87, 0x2F, 0x64, 0x90, 0xA7, 0x2F, 0x68,
|
||||
0x90, 0xC7, 0x2F, 0x6C, 0x80, 0x03, 0x00, 0x04, 0x90, 0x07, 0x2F, 0x70, 0x38, 0x00, 0x00, 0x03,
|
||||
0x90, 0x07, 0x2F, 0x78, 0x80, 0x07, 0x2F, 0x78, 0x2C, 0x00, 0x00, 0x03, 0x41, 0x82, 0xFF, 0xF8,
|
||||
0x80, 0x07, 0x2F, 0x9C, 0x70, 0x00, 0x00, 0x14, 0x2C, 0x00, 0x00, 0x00, 0x41, 0x82, 0xFF, 0xF4,
|
||||
0x3C, 0xC0, 0xD2, 0x01, 0x80, 0x06, 0x00, 0x00, 0x90, 0x04, 0x00, 0x00, 0x34, 0xA5, 0xFF, 0xFC,
|
||||
0x84, 0x06, 0x00, 0x04, 0x94, 0x04, 0x00, 0x04, 0x34, 0xA5, 0xFF, 0xFC, 0x40, 0x82, 0xFF, 0xF4,
|
||||
0x2C, 0x0C, 0x00, 0x00, 0x41, 0x82, 0x00, 0x14, 0x7D, 0x88, 0x03, 0xA6, 0x38, 0x60, 0x00, 0x00,
|
||||
0x38, 0x80, 0x00, 0x00, 0x4E, 0x80, 0x00, 0x21, 0x38, 0x60, 0x00, 0x00, 0x7C, 0x64, 0x1B, 0x78,
|
||||
0xBB, 0x61, 0x00, 0x14, 0x80, 0x01, 0x00, 0x2C, 0x38, 0x21, 0x00, 0x28, 0x7C, 0x08, 0x03, 0xA6,
|
||||
0x4E, 0x80, 0x00, 0x20
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user