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:
crediar@rypp.net
2014-04-27 13:07:28 +00:00
commit 9a86d28ba7
255 changed files with 28131 additions and 0 deletions

37
Build.bat Normal file
View 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

View 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
View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

View 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

View File

@@ -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

View File

@@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

94
kernel/Patch.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
};

View File

@@ -0,0 +1,6 @@
#include <asm.h>
ARGetBaseAddress:
lis %r3, 0x2000
oris %r3, %r3, 0x4000
blr

View 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
View 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
View 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
View 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

View 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
View 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
View 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
};

View File

@@ -0,0 +1,7 @@
#include <asm.h>
AXSetVoiceAdr:
oris %r31, %r4, 0x2000
blr

View 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
};

View 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

View 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
View 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
View 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
};

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
};

View 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

View 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
View 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
View 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
};

View 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

View 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
};

View 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

View 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
};

View 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

View 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
};

View 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

View 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
};

View 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

View 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
View 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
View 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
};

View 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

View 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
View 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
View 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
};

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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