diff --git a/common/include/NintendontVersion.h b/common/include/NintendontVersion.h index e23e339..5172a41 100644 --- a/common/include/NintendontVersion.h +++ b/common/include/NintendontVersion.h @@ -2,7 +2,7 @@ #define __NINTENDONT_VERSION_H__ #define NIN_MAJOR_VERSION 5 -#define NIN_MINOR_VERSION 457 +#define NIN_MINOR_VERSION 458 #define NIN_VERSION ((NIN_MAJOR_VERSION << 16) | NIN_MINOR_VERSION) diff --git a/kernel/BT.c b/kernel/BT.c index 758994c..0f4e80f 100644 --- a/kernel/BT.c +++ b/kernel/BT.c @@ -43,8 +43,8 @@ static struct linkkey_info BTKeys[CONF_PAD_MAX_REGISTERED] ALIGNED(32); static struct BTPadCont *BTPad = (struct BTPadCont*)0x132F0000; -static vu32* BTMotor = (u32*)0x13002720; -static vu32* BTPadFree = (u32*)0x13002730; +static vu32* BTMotor = (u32*)0x13003040; +static vu32* BTPadFree = (u32*)0x13003050; static vu32* IRSensitivity = (u32*)0x132C0490; static vu32* SensorBarPosition = (u32*)0x132C0494; @@ -752,7 +752,7 @@ void BTUpdateRegisters(void) } u32 i = 0, j = 0; - sync_before_read((void*)0x13002700,0x40); + sync_before_read((void*)0x13003020,0x40); for( ; i < BTChannelsUsed; ++i) { sync_before_read(BTPadConnected[i], sizeof(struct BTPadStat)); diff --git a/kernel/Config.h b/kernel/Config.h index 6390a0e..9b5d431 100644 --- a/kernel/Config.h +++ b/kernel/Config.h @@ -47,7 +47,7 @@ void ConfigInit( void ); extern u32 BI2region; // Nintendont configuration. -static NIN_CFG *const ncfg = (NIN_CFG*)0x13002900; +static NIN_CFG *const ncfg = (NIN_CFG*)0x13004000; // NOTE: DIChangeDisc() modifies this path. static inline char *ConfigGetGamePath(void) diff --git a/kernel/DI.c b/kernel/DI.c index 279b0a6..eef3781 100644 --- a/kernel/DI.c +++ b/kernel/DI.c @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "global.h" #include "DI.h" #include "RealDI.h" +#include "wdvd.h" #include "string.h" #include "common.h" #include "alloc.h" @@ -66,7 +67,9 @@ extern const u8 *DiskDriveInfo; extern u32 FSTMode; extern u32 RealDiscCMD; extern u32 RealDiscError; +extern bool wiiVCInternal; u32 WaitForRealDisc = 0; +u32 DiscRequested = 0; u8 *const DI_READ_BUFFER = (u8*)0x12E80000; const u32 DI_READ_BUFFER_LENGTH = 0x80000; @@ -161,7 +164,14 @@ void DIinit( bool FirstTime ) if (FirstTime) { - if(RealDiscCMD == 0) + if(wiiVCInternal) + { + if(WDVD_Init() != 0) + Shutdown(); + if(!WDVD_FST_Mount()) + Shutdown(); + } + else if(RealDiscCMD == 0) { // Check if this is a 2-disc game. u32 i, slash_pos; @@ -260,27 +270,36 @@ void DISetDIMMVersion( u32 Version ) } bool DIChangeDisc( u32 DiscNumber ) { - // Don't do anything if multi-disc mode isn't enabled. - if (!DI_2disc_filenames[0] || - !DI_2disc_filenames[1] || - DiscNumber > 1) + if(wiiVCInternal) { - return false; + if(DiscNumber > 1) + return false; + DiscRequested = DiscNumber; } - - u32 slash_pos; - char* DiscName = ConfigGetGamePath(); - - //search the string backwards for '/' - for (slash_pos = strlen(DiscName); slash_pos > 0; --slash_pos) + else { - if (DiscName[slash_pos] == '/') - break; - } - slash_pos++; + // Don't do anything if multi-disc mode isn't enabled. + if (!DI_2disc_filenames[0] || + !DI_2disc_filenames[1] || + DiscNumber > 1) + { + return false; + } - _sprintf(DiscName+slash_pos, DI_2disc_filenames[DiscNumber]); - dbgprintf("New Gamepath:\"%s\"\r\n", DiscName ); + u32 slash_pos; + char* DiscName = ConfigGetGamePath(); + + //search the string backwards for '/' + for (slash_pos = strlen(DiscName); slash_pos > 0; --slash_pos) + { + if (DiscName[slash_pos] == '/') + break; + } + slash_pos++; + + _sprintf(DiscName+slash_pos, DI_2disc_filenames[DiscNumber]); + dbgprintf("New Gamepath:\"%s\"\r\n", DiscName ); + } DIinit(false); return true; } @@ -901,7 +920,7 @@ void DIFinishAsync() BTUpdateRegisters(); } } - +/* struct _TGCInfo { u32 tgcoffset; @@ -912,7 +931,7 @@ struct _TGCInfo u32 fstupdate; u32 isTGC; }; -static struct _TGCInfo *const TGCInfo = (struct _TGCInfo*)0x13002FE0; +static struct _TGCInfo *const TGCInfo = (struct _TGCInfo*)0x130031E0; #define PATCH_STATE_PATCH 2 extern u32 PatchState, DOLSize, DOLMinOff, DOLMaxOff; @@ -955,3 +974,4 @@ bool DICheckTGC(u32 Buffer, u32 Length) dbgprintf("Game is loading another DOL\n"); return false; } +*/ \ No newline at end of file diff --git a/kernel/HID.c b/kernel/HID.c index b09e744..6e03d7d 100644 --- a/kernel/HID.c +++ b/kernel/HID.c @@ -675,7 +675,7 @@ void HIDPS3SetRumble( u8 duration_right, u8 power_right, u8 duration_left, u8 po } vu32 HIDRumbleCurrent = 0, HIDRumbleLast = 0; -vu32 MotorCommand = 0x13002700; +vu32 MotorCommand = 0x13003020; void HIDPS3Read() { if( !PS3LedSet && Packet[4] ) diff --git a/kernel/ISO.c b/kernel/ISO.c index 878593c..af96d90 100644 --- a/kernel/ISO.c +++ b/kernel/ISO.c @@ -21,10 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "FST.h" #include "DI.h" #include "debug.h" +#include "wdvd.h" #include "ff_utf8.h" extern u32 TRIGame; +extern u32 DiscRequested; +extern bool wiiVCInternal; u32 ISOFileOpen = 0; @@ -86,9 +89,19 @@ static inline void ISOReadDirect(void *Buffer, u32 Length, u64 Offset64) { // Standard ISO/GCM file. if(LastOffset64 != Offset64) - f_lseek( &GameFile, Offset64 ); - - f_read( &GameFile, Buffer, Length, &read ); + { + if(wiiVCInternal) + WDVD_FST_LSeek( Offset64 ); + else + f_lseek( &GameFile, Offset64 ); + } + if(wiiVCInternal) + { + sync_before_read( Buffer, Length ); + read = WDVD_FST_Read( Buffer, Length ); + } + else + f_read( &GameFile, Buffer, Length, &read ); } else { @@ -124,9 +137,18 @@ static inline void ISOReadDirect(void *Buffer, u32 Length, u64 Offset64) { // Seek to the physical block address. const u32 physBlockStartAddr = CISO_HEADER_SIZE + ((u32)physBlockStartIdx * CISO_BLOCK_SIZE); - f_lseek(&GameFile, physBlockStartAddr + blockStartOffset); - // Read read_sz bytes. - f_read(&GameFile, ptr8, read_sz, &read); + if(wiiVCInternal) + { + WDVD_FST_LSeek( physBlockStartAddr + blockStartOffset ); + sync_before_read( ptr8, read_sz ); + read = WDVD_FST_Read( ptr8, read_sz ); + } + else + { + f_lseek(&GameFile, physBlockStartAddr + blockStartOffset); + // Read read_sz bytes. + f_read(&GameFile, ptr8, read_sz, &read); + } if (read != read_sz) { // Error reading the data. @@ -162,9 +184,18 @@ static inline void ISOReadDirect(void *Buffer, u32 Length, u64 Offset64) { // Seek to the physical block address. const u32 physBlockAddr = CISO_HEADER_SIZE + ((u32)physBlockIdx * CISO_BLOCK_SIZE); - f_lseek(&GameFile, physBlockAddr); - // Read one block worth of data. - f_read(&GameFile, ptr8, CISO_BLOCK_SIZE, &read); + if(wiiVCInternal) + { + WDVD_FST_LSeek( physBlockAddr ); + sync_before_read( ptr8, CISO_BLOCK_SIZE ); + read = WDVD_FST_Read( ptr8, CISO_BLOCK_SIZE ); + } + else + { + f_lseek(&GameFile, physBlockAddr); + // Read one block worth of data. + f_read(&GameFile, ptr8, CISO_BLOCK_SIZE, &read); + } if (read != CISO_BLOCK_SIZE) { // Error reading the data. @@ -195,9 +226,18 @@ static inline void ISOReadDirect(void *Buffer, u32 Length, u64 Offset64) { // Seek to the physical block address. const u32 physBlockEndAddr = CISO_HEADER_SIZE + ((u32)physBlockEndIdx * CISO_BLOCK_SIZE); - f_lseek(&GameFile, physBlockEndAddr); - // Read Length bytes. - f_read(&GameFile, ptr8, Length, &read); + if(wiiVCInternal) + { + WDVD_FST_LSeek( physBlockEndAddr ); + sync_before_read( ptr8, Length ); + read = WDVD_FST_Read( ptr8, Length ); + } + else + { + f_lseek(&GameFile, physBlockEndAddr); + // Read Length bytes. + f_read(&GameFile, ptr8, Length, &read); + } if (read != Length) { // Error reading the data. @@ -216,29 +256,38 @@ static inline void ISOReadDirect(void *Buffer, u32 Length, u64 Offset64) // ISO shift offset. extern u64 ISOShift64; +static u8 isoTmpBuf[0x20] ALIGNED(32); bool ISOInit() { - s32 ret = f_open_char( &GameFile, ConfigGetGamePath(), FA_READ|FA_OPEN_EXISTING ); - if( ret != FR_OK ) - return false; + if(wiiVCInternal) + { + if(WDVD_FST_OpenDisc(DiscRequested) != 0) + Shutdown(); + } + else + { + s32 ret = f_open_char( &GameFile, ConfigGetGamePath(), FA_READ|FA_OPEN_EXISTING ); + if( ret != FR_OK ) + return false; #if _USE_FASTSEEK - /* Setup table */ - u32 tblsize = 4; //minimum default size - GameFile.cltbl = malloc(tblsize * sizeof(DWORD)); - GameFile.cltbl[0] = tblsize; - ret = f_lseek(&GameFile, CREATE_LINKMAP); - if( ret == FR_NOT_ENOUGH_CORE ) - { /* We need more table mem */ - tblsize = GameFile.cltbl[0]; - free(GameFile.cltbl); - dbgprintf("ISO:Fragmented, allocating %08x\r\n", tblsize); + /* Setup table */ + u32 tblsize = 4; //minimum default size GameFile.cltbl = malloc(tblsize * sizeof(DWORD)); GameFile.cltbl[0] = tblsize; - f_lseek(&GameFile, CREATE_LINKMAP); - } + ret = f_lseek(&GameFile, CREATE_LINKMAP); + if( ret == FR_NOT_ENOUGH_CORE ) + { /* We need more table mem */ + tblsize = GameFile.cltbl[0]; + free(GameFile.cltbl); + dbgprintf("ISO:Fragmented, allocating %08x\r\n", tblsize); + GameFile.cltbl = malloc(tblsize * sizeof(DWORD)); + GameFile.cltbl[0] = tblsize; + f_lseek(&GameFile, CREATE_LINKMAP); + } #endif /* _USE_FASTSEEK */ + } /* Setup direct reader */ ISOFileOpen = 1; @@ -293,17 +342,20 @@ bool ISOInit() free(tmp_ciso); /* Set Low Mem */ - ISOReadDirect((void*)0x0, 0x20, 0x0 + ISOShift64); + ISOReadDirect(isoTmpBuf, 0x20, 0x0 + ISOShift64); + memcpy((void*)0x0, isoTmpBuf, 0x20); sync_after_write((void*)0x0, 0x20); //used by game so sync it /* Get BI2.bin region code */ - ISOReadDirect(&BI2region, sizeof(BI2region), 0x458 + ISOShift64); + ISOReadDirect(isoTmpBuf, sizeof(BI2region), 0x458 + ISOShift64); + memcpy(&BI2region, isoTmpBuf, sizeof(BI2region)); /* Reset Cache */ CacheInited = 0; if ((read32(0) == 0x474E4845) && (read32(4) == 0x35640000)) { u32 DatelName[2]; - ISOReadDirect(DatelName, 2 * sizeof(u32), 0x19848 + ISOShift64); + ISOReadDirect(isoTmpBuf, 2 * sizeof(u32), 0x19848 + ISOShift64); + memcpy(DatelName, isoTmpBuf, 2 * sizeof(u32)); if ((DatelName[0] == 0x20446174) && ((DatelName[1] >> 16) == 0x656C)) Datel = true; } @@ -314,11 +366,16 @@ void ISOClose() { if(ISOFileOpen) { - f_close( &GameFile ); + if(wiiVCInternal) + WDVD_FST_Close(); + else + { + f_close( &GameFile ); #if _USE_FASTSEEK - free(GameFile.cltbl); - GameFile.cltbl = NULL; + free(GameFile.cltbl); + GameFile.cltbl = NULL; #endif /* _USE_FASTSEEK */ + } } ISOFileOpen = 0; ISO_IsCISO = false; @@ -376,11 +433,17 @@ void ISOSeek(u32 Offset) const u32 blockOffset = (u32)(Offset64 % CISO_BLOCK_SIZE); const u32 physAddr = CISO_HEADER_SIZE + ((u32)physBlockIdx * CISO_BLOCK_SIZE) + blockOffset; - f_lseek( &GameFile, physAddr ); + if(wiiVCInternal) + WDVD_FST_LSeek( physAddr ); + else + f_lseek( &GameFile, physAddr ); } else { - f_lseek( &GameFile, Offset64 ); + if(wiiVCInternal) + WDVD_FST_LSeek( Offset64 ); + else + f_lseek( &GameFile, Offset64 ); } LastOffset64 = Offset64; } diff --git a/kernel/JVSIO.c b/kernel/JVSIO.c index f22e939..8572edf 100644 --- a/kernel/JVSIO.c +++ b/kernel/JVSIO.c @@ -23,8 +23,8 @@ vu32 AXTimerOffset = 0; static const char TRI_SegaChar[] = "SEGA ENTERPRISES,LTD.;I/O BD JVS;837-13551;Ver1.00"; static const char TRI_NamcoChar[] = "namco ltd.;FCA-1;Ver1.01;JPN,Multipurpose + Rotary Encoder"; -static const PADStatus *PadBuff = (PADStatus*)0x13002800; -static const vu32 *IN_TESTMENU = (vu32*)0x13002760; +static const PADStatus *PadBuff = (PADStatus*)0x13003100; +static const vu32 *IN_TESTMENU = (vu32*)0x13003080; static u32 TestMenuTimer = 0, TestMenuTimerRunning = 0; static u32 CoinAddTimer = 0; diff --git a/kernel/JVSIO.h b/kernel/JVSIO.h index 1056dd8..2ca62a1 100644 --- a/kernel/JVSIO.h +++ b/kernel/JVSIO.h @@ -3,8 +3,6 @@ #include "global.h" -#define TRIButtons 0x13002708 - void JVSIOCommand( char *DataIn, char *DataOut ); #endif diff --git a/kernel/Patch.c b/kernel/Patch.c index b007723..43f4173 100644 --- a/kernel/Patch.c +++ b/kernel/Patch.c @@ -3655,12 +3655,12 @@ void PatchGame() // Didn't look for why PMW2 requires this. ToDo if ((TITLE_ID) == 0x475032 || TRIGame) // PacMan World 2 and Triforce hack SiInitSet = 1; - write32(0x13002740, SiInitSet); //Clear SI Inited == 0 - write32(0x13002744, PADSwitchRequired() && (useipl == 0)); - write32(0x13002748, PADForceConnected() && (useipl == 0)); - write32(0x1300274C, drcAddress); //Set on kernel boot - write32(0x13002750, drcAddressAligned); //Set on kernel boot - sync_after_write((void*)0x13002740, 0x20); + write32(0x13003060, SiInitSet); //Clear SI Inited == 0 + write32(0x13003064, PADSwitchRequired() && (useipl == 0)); + write32(0x13003068, PADForceConnected() && (useipl == 0)); + write32(0x1300306C, drcAddress); //Set on kernel boot + write32(0x13003070, drcAddressAligned); //Set on kernel boot + sync_after_write((void*)0x13003060, 0x20); /* Clear very actively used areas */ memset32((void*)0x13026500, 0, 0x100); sync_after_write((void*)0x13026500, 0x100); diff --git a/kernel/RealDI.c b/kernel/RealDI.c index 1a0ed68..b3f455f 100644 --- a/kernel/RealDI.c +++ b/kernel/RealDI.c @@ -22,7 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "string.h" #include "alloc.h" #include "RealDI.h" -#include "wdvd.h" #include "DI.h" static struct ipcmessage realdimsg ALIGNED(32); @@ -57,56 +56,45 @@ u32 RealDI_Thread(void *arg) extern char __realdi_stack_addr, __realdi_stack_size; static u32 RealDI_Thread_P = 0; static u8 *realdiheap = NULL; -extern bool isWiiVC; void RealDI_Init() { - if(isWiiVC) - { - if(WDVD_Init() != 0) - Shutdown(); - if(!WDVD_FST_Mount()) - Shutdown(); - if(WDVD_FST_Open("game.iso") != 0) - Shutdown(); - } - else - { - memset32(spinup, 0, 32); - spinup[0] = 0x8A000000; - spinup[1] = 1; - sync_after_write(spinup, 32); + memset32(spinup, 0, 32); + spinup[0] = 0x8A000000; + spinup[1] = 1; + sync_after_write(spinup, 32); - memset32(identify, 0, 32); - identify[0] = 0x12000000; - sync_after_write(identify, 32); + memset32(identify, 0, 32); + identify[0] = 0x12000000; + sync_after_write(identify, 32); - memset32(readdiscid, 0, 32); - readdiscid[0] = 0x70000000; - sync_after_write(readdiscid, 32); + memset32(readdiscid, 0, 32); + readdiscid[0] = 0x70000000; + sync_after_write(readdiscid, 32); - //have real disc drive ready - di_fd = IOS_Open(di_path, 0); + //have real disc drive ready + di_fd = IOS_Open(di_path, 0); - realdiheap = (u8*)malloca(32,32); - realdiqueue = mqueue_create(realdiheap, 1); + realdiheap = (u8*)malloca(32,32); + realdiqueue = mqueue_create(realdiheap, 1); + + RealDI_Thread_P = do_thread_create(RealDI_Thread, ((u32*)&__realdi_stack_addr), ((u32)(&__realdi_stack_size)), 0x50); + thread_continue(RealDI_Thread_P); + mdelay(100); - RealDI_Thread_P = do_thread_create(RealDI_Thread, ((u32*)&__realdi_stack_addr), ((u32)(&__realdi_stack_size)), 0x50); - thread_continue(RealDI_Thread_P); - mdelay(100); - } RealDI_Identify(true); } void RealDI_Identify(bool NeedsGC) { ClearRealDiscBuffer(); - u32 Length; - const u8 *TmpBuf; - if(isWiiVC) + u32 Length = 0x800; + RealDiscCMD = DIP_CMD_NORMAL; + const u8 * TmpBuf = ReadRealDisc(&Length, 0, false); + if(IsGCGame((u32)TmpBuf) == false) { Length = 0x800; - RealDiscCMD = DIP_CMD_WIIVC; + RealDiscCMD = DIP_CMD_DVDR; TmpBuf = ReadRealDisc(&Length, 0, false); if(IsGCGame((u32)TmpBuf) == false) { @@ -122,31 +110,6 @@ void RealDI_Identify(bool NeedsGC) return; } } - else - { - Length = 0x800; - RealDiscCMD = DIP_CMD_NORMAL; - TmpBuf = ReadRealDisc(&Length, 0, false); - if(IsGCGame((u32)TmpBuf) == false) - { - Length = 0x800; - RealDiscCMD = DIP_CMD_DVDR; - TmpBuf = ReadRealDisc(&Length, 0, false); - if(IsGCGame((u32)TmpBuf) == false) - { - if(NeedsGC) - { - dbgprintf("No GC Disc!\r\n"); - BootStatusError(-2, -2); - mdelay(4000); - Shutdown(); - } - else - dbgprintf("No GC Disc, continuing anyways\r\n"); - return; - } - } - } memcpy((void*)0, TmpBuf, 0x20); //Disc Header sync_after_write((void*)0, 0x20); BI2region = read32((u32)(TmpBuf+0x458)); // BI2.bin region code @@ -156,8 +119,6 @@ void RealDI_Identify(bool NeedsGC) static vu32 WaitForWrite = 0, WaitForRead = 0; void RealDI_Update() { - if(isWiiVC) - return; if(WaitForWrite == 1) { WaitForWrite = 0; @@ -177,8 +138,6 @@ void RealDI_Update() static u32 switch_stat = 0; bool RealDI_NewDisc() { - if(isWiiVC) - return false; if(switch_stat == 0 && read32(DIP_COVER) == 4) //disc switch! { realdi_msgrecv = 0; @@ -227,32 +186,29 @@ const u8 *ReadRealDisc(u32 *Length, u32 Offset, bool NeedSync) u32 TmpLen = *Length; u64 TmpOffset = (u64)Offset + ISOShift64; - if(RealDiscCMD != DIP_CMD_WIIVC) + if(RealDiscCMD == DIP_CMD_DVDR) { - if(RealDiscCMD == DIP_CMD_DVDR) + // Wii's disc drive can only read full ISO-9660 + // sectors when using standard DVD media. (2048 bytes) + u64 AlignedOffset = ALIGN_BACKWARD(TmpOffset, 0x800); + ReadDiff = (u32)(TmpOffset - AlignedOffset); + if(AlignedOffset == DVD_OFFSET64) { - // Wii's disc drive can only read full ISO-9660 - // sectors when using standard DVD media. (2048 bytes) - u64 AlignedOffset = ALIGN_BACKWARD(TmpOffset, 0x800); - ReadDiff = (u32)(TmpOffset - AlignedOffset); - if(AlignedOffset == DVD_OFFSET64) - { - sync_before_read(DISC_TMP_CACHE, 0x800); - //dbgprintf("Using cached offset %08llx\r\n", DVD_OFFSET64>>11); - memcpy(DISC_FRONT_CACHE, DISC_TMP_CACHE, 0x800); - CachedBlockStart = 0x800; - u32 AlignedLength = ALIGN_FORWARD(TmpLen + ReadDiff, 0x800); - if( AlignedLength > 0 && AlignedLength == CachedBlockStart ) - return (DISC_FRONT_CACHE + ReadDiff); - } - //dbgprintf("ReadDiff: %08x\r\n", ReadDiff); - } - if(NeedSync) - { - WaitForWrite = 1; - while(WaitForWrite == 1) - udelay(20); + sync_before_read(DISC_TMP_CACHE, 0x800); + //dbgprintf("Using cached offset %08llx\r\n", DVD_OFFSET64>>11); + memcpy(DISC_FRONT_CACHE, DISC_TMP_CACHE, 0x800); + CachedBlockStart = 0x800; + u32 AlignedLength = ALIGN_FORWARD(TmpLen + ReadDiff, 0x800); + if( AlignedLength > 0 && AlignedLength == CachedBlockStart ) + return (DISC_FRONT_CACHE + ReadDiff); } + //dbgprintf("ReadDiff: %08x\r\n", ReadDiff); + } + if(NeedSync) + { + WaitForWrite = 1; + while(WaitForWrite == 1) + udelay(20); } //turn on drive led @@ -265,55 +221,46 @@ const u8 *ReadRealDisc(u32 *Length, u32 Offset, bool NeedSync) //dbgprintf("New Length: %08x\r\n", TmpLen); } - if(RealDiscCMD == DIP_CMD_WIIVC) + write32(DIP_STATUS, 0x54); //mask and clear interrupts + + //Actually read + if (RealDiscCMD == DIP_CMD_DVDR) { - //dbgprintf("Wii VC Read\r\n"); - sync_before_read(DISC_DRIVE_BUFFER, TmpLen); - WDVD_FST_Read(DISC_DRIVE_BUFFER, TmpOffset, TmpLen); + // Adjust length and offset for DVD-R mode. + TmpLen = ALIGN_FORWARD(TmpLen + ReadDiff, 0x800) - CachedBlockStart; + TmpOffset = ALIGN_BACKWARD(TmpOffset, 0x800) + CachedBlockStart; + + write32(DIP_CMD_0, DIP_CMD_DVDR << 24); + write32(DIP_CMD_1, (u32)(TmpOffset >> 11)); + write32(DIP_CMD_2, TmpLen >> 11); } else { + write32(DIP_CMD_0, DIP_CMD_NORMAL << 24); + write32(DIP_CMD_1, (u32)(TmpOffset >> 2)); + write32(DIP_CMD_2, TmpLen); + } + + //dbgprintf("Read %08x %08x\r\n", read32(DIP_CMD_1), read32(DIP_CMD_2)); + sync_before_read(DISC_DRIVE_BUFFER, TmpLen); + write32(DIP_DMA_ADR, (u32)DISC_DRIVE_BUFFER); + write32(DIP_DMA_LEN, TmpLen); + + write32( DIP_CONTROL, 3 ); + udelay(70); + + if(NeedSync) + { + WaitForRead = 1; + while(WaitForRead == 1) + udelay(200); + } + else + { + while(read32(DIP_CONTROL) & 1) + udelay(200); write32(DIP_STATUS, 0x54); //mask and clear interrupts - - //Actually read - if (RealDiscCMD == DIP_CMD_DVDR) - { - // Adjust length and offset for DVD-R mode. - TmpLen = ALIGN_FORWARD(TmpLen + ReadDiff, 0x800) - CachedBlockStart; - TmpOffset = ALIGN_BACKWARD(TmpOffset, 0x800) + CachedBlockStart; - - write32(DIP_CMD_0, DIP_CMD_DVDR << 24); - write32(DIP_CMD_1, (u32)(TmpOffset >> 11)); - write32(DIP_CMD_2, TmpLen >> 11); - } - else - { - write32(DIP_CMD_0, DIP_CMD_NORMAL << 24); - write32(DIP_CMD_1, (u32)(TmpOffset >> 2)); - write32(DIP_CMD_2, TmpLen); - } - - //dbgprintf("Read %08x %08x\r\n", read32(DIP_CMD_1), read32(DIP_CMD_2)); - sync_before_read(DISC_DRIVE_BUFFER, TmpLen); - write32(DIP_DMA_ADR, (u32)DISC_DRIVE_BUFFER); - write32(DIP_DMA_LEN, TmpLen); - - write32( DIP_CONTROL, 3 ); udelay(70); - - if(NeedSync) - { - WaitForRead = 1; - while(WaitForRead == 1) - udelay(200); - } - else - { - while(read32(DIP_CONTROL) & 1) - udelay(200); - write32(DIP_STATUS, 0x54); //mask and clear interrupts - udelay(70); - } } //turn off drive led diff --git a/kernel/RealDI.h b/kernel/RealDI.h index 1762e69..1e48bf7 100644 --- a/kernel/RealDI.h +++ b/kernel/RealDI.h @@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef _REALDI_H_ #define _REALDI_H_ -#define DIP_CMD_WIIVC 0x71 #define DIP_CMD_NORMAL 0xA8 #define DIP_CMD_DVDR 0xD0 diff --git a/kernel/SI.c b/kernel/SI.c index 4480f70..540f94d 100644 --- a/kernel/SI.c +++ b/kernel/SI.c @@ -93,7 +93,7 @@ void SIUpdateRegisters() //cur_control &= ~(1 << 29); //we normally always have some communication error? u32 chan = (cur_control >> 1) & 0x3; u32 ChanBuff = PAD_BUFF + (chan * 0xC); - bool PadGood = !!(read32(0x13002704) & (1<= ConfigGetMaxPads()) PadGood = false; switch ((read32(SI_IO_BUF) >> 24) & 0xFF) diff --git a/kernel/SI.h b/kernel/SI.h index aeea9a0..e562e39 100644 --- a/kernel/SI.h +++ b/kernel/SI.h @@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define SI_EXI_LOCK (SI_BASE+0x3C) #define SI_IO_BUF (SI_BASE+0x80) -#define PAD_BUFF 0x13002800 +#define PAD_BUFF 0x13003100 void SIInit(); void SIInterrupt(); diff --git a/kernel/TRI.c b/kernel/TRI.c index e5748e5..27a88b1 100644 --- a/kernel/TRI.c +++ b/kernel/TRI.c @@ -61,7 +61,7 @@ static const char SETTINGS_VS4V06EXP[] = "/saves/VS4V06EXPsettings.bin"; static const char *TRISettingsName = (char*)0; static u32 TRISettingsLoc = 0, TRISettingsSize = 0; -static void *OUR_SETTINGS_LOC = (void*)0x13002780; +static void *OUR_SETTINGS_LOC = (void*)0x13003500; #ifndef DEBUG_PATCH #define dbgprintf(...) diff --git a/kernel/asm/ARStartDMA.S b/kernel/asm/ARStartDMA.S index 8bf29d8..9eab4cf 100644 --- a/kernel/asm/ARStartDMA.S +++ b/kernel/asm/ARStartDMA.S @@ -3,7 +3,7 @@ .set AR_DMA_CNT, 0xCC005028 .set OSReport, 0xC0001860 -.set AR_DBG, 0x930028A0 +.set AR_DBG, 0x930031A0 .set AR_MRAM_TO_ARAM, 0 .set AR_ARAM_TO_MRAM, 1 diff --git a/kernel/asm/ARStartDMA_Hook.S b/kernel/asm/ARStartDMA_Hook.S index 34ca074..6f6afee 100644 --- a/kernel/asm/ARStartDMA_Hook.S +++ b/kernel/asm/ARStartDMA_Hook.S @@ -3,7 +3,7 @@ .set AR_DMA_SAVE, 0x931C0040 .set OSReport, 0xC0001860 -.set AR_DBG, 0x930028A0 +.set AR_DBG, 0x930031A0 #in # r29 u32 type diff --git a/kernel/asm/CheckTestMenu.S b/kernel/asm/CheckTestMenu.S index e0415cb..7090844 100644 --- a/kernel/asm/CheckTestMenu.S +++ b/kernel/asm/CheckTestMenu.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set IN_TESTMENU, 0xD3002760 #uncached for kernel +.set IN_TESTMENU, 0xD3003080 #uncached for kernel #r3 gets overwritten later diff --git a/kernel/asm/CheckTestMenuGP.S b/kernel/asm/CheckTestMenuGP.S index c11e69c..7dc8e01 100644 --- a/kernel/asm/CheckTestMenuGP.S +++ b/kernel/asm/CheckTestMenuGP.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set IN_TESTMENU, 0xD3002760 #uncached for kernel +.set IN_TESTMENU, 0xD3003080 #uncached for kernel #r3 gets overwritten later diff --git a/kernel/asm/CheckTestMenuVS.S b/kernel/asm/CheckTestMenuVS.S index 9cd104d..e32a5b1 100644 --- a/kernel/asm/CheckTestMenuVS.S +++ b/kernel/asm/CheckTestMenuVS.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set IN_TESTMENU, 0xD3002760 #uncached for kernel +.set IN_TESTMENU, 0xD3003080 #uncached for kernel #r6 is unused at this point diff --git a/kernel/asm/CheckTestMenuYakyuu.S b/kernel/asm/CheckTestMenuYakyuu.S index dcbd18d..3062f4e 100644 --- a/kernel/asm/CheckTestMenuYakyuu.S +++ b/kernel/asm/CheckTestMenuYakyuu.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set IN_TESTMENU, 0xD3002760 #uncached for kernel +.set IN_TESTMENU, 0xD3003080 #uncached for kernel #r6 is unused at this point diff --git a/kernel/asm/EXIProbe.S b/kernel/asm/EXIProbe.S index f9add07..01aad98 100644 --- a/kernel/asm/EXIProbe.S +++ b/kernel/asm/EXIProbe.S @@ -1,6 +1,6 @@ #include -.set NinCfg, 0xD3002900 +.set NinCfg, 0xD3004000 .set NinCfgConfig, NinCfg + 0x8 #in diff --git a/kernel/asm/PADIsBarrel.S b/kernel/asm/PADIsBarrel.S index 7436ee5..2f2ae1e 100644 --- a/kernel/asm/PADIsBarrel.S +++ b/kernel/asm/PADIsBarrel.S @@ -7,7 +7,7 @@ PADIsBarrel: bgt invalid lis %r0, 0xD300 - ori %r0, %r0, 0x2830 #chan0 base + ori %r0, %r0, 0x3130 #chan0 base slwi %r3, %r3, 2 lwzx %r3, %r3, %r0 blr diff --git a/kernel/asm/PADRead.S b/kernel/asm/PADRead.S index 0caf67b..2cad950 100644 --- a/kernel/asm/PADRead.S +++ b/kernel/asm/PADRead.S @@ -1,7 +1,7 @@ #include .set PadStub, 0x93000000 -.set PadBuff, 0x93002800 +.set PadBuff, 0x93003100 PADRead: stwu %sp, -0x20(%sp) diff --git a/kernel/asm/PADReadF.S b/kernel/asm/PADReadF.S index 09cc407..e80696a 100644 --- a/kernel/asm/PADReadF.S +++ b/kernel/asm/PADReadF.S @@ -1,7 +1,7 @@ #include .set PadStub, 0x93000000 -.set PadBuff, 0x93002800 +.set PadBuff, 0x93003100 PADReadF: #only update player 1 diff --git a/kernel/asm/PADReadGP.S b/kernel/asm/PADReadGP.S index dc707a1..3e56992 100644 --- a/kernel/asm/PADReadGP.S +++ b/kernel/asm/PADReadGP.S @@ -1,7 +1,7 @@ #include .set PadStub, 0x93000000 -.set PadBuff, 0x93002800 +.set PadBuff, 0x93003100 PADReadGP: #original instruction diff --git a/kernel/asm/PADReadVS.S b/kernel/asm/PADReadVS.S index 3cd99b6..10f1ef6 100644 --- a/kernel/asm/PADReadVS.S +++ b/kernel/asm/PADReadVS.S @@ -1,7 +1,7 @@ #include .set PadStub, 0x93000000 -.set PadBuff, 0x93002800 +.set PadBuff, 0x93003100 PADReadVS: #original instruction diff --git a/kernel/asm/PADReadVS3.S b/kernel/asm/PADReadVS3.S index 49b5dbc..debbc70 100644 --- a/kernel/asm/PADReadVS3.S +++ b/kernel/asm/PADReadVS3.S @@ -1,7 +1,7 @@ #include .set PadStub, 0x93000000 -.set PadBuff, 0x93002800 +.set PadBuff, 0x93003100 PADReadVS3: #original instruction diff --git a/kernel/asm/RestoreSettingsAX_RVC.S b/kernel/asm/RestoreSettingsAX_RVC.S index 5adeb87..44d63f3 100644 --- a/kernel/asm/RestoreSettingsAX_RVC.S +++ b/kernel/asm/RestoreSettingsAX_RVC.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set AX_BACKUP, 0xD3002780 +.set AX_BACKUP, 0xD3003500 .set AX_DEST, 0x803CF6F0 RestoreSettingsAX: diff --git a/kernel/asm/RestoreSettingsAX_RVD.S b/kernel/asm/RestoreSettingsAX_RVD.S index 3370ffe..30be7e6 100644 --- a/kernel/asm/RestoreSettingsAX_RVD.S +++ b/kernel/asm/RestoreSettingsAX_RVD.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set AX_BACKUP, 0xD3002780 +.set AX_BACKUP, 0xD3003500 .set AX_DEST, 0x803CFBD0 RestoreSettingsAX: diff --git a/kernel/asm/RestoreSettingsAX_RVE.S b/kernel/asm/RestoreSettingsAX_RVE.S index d456bb4..381f873 100644 --- a/kernel/asm/RestoreSettingsAX_RVE.S +++ b/kernel/asm/RestoreSettingsAX_RVE.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set AX_BACKUP, 0xD3002780 +.set AX_BACKUP, 0xD3003500 .set AX_DEST, 0x803D0150 RestoreSettingsAX: diff --git a/kernel/asm/RestoreSettingsVS3V02.S b/kernel/asm/RestoreSettingsVS3V02.S index dcc3141..83da05d 100644 --- a/kernel/asm/RestoreSettingsVS3V02.S +++ b/kernel/asm/RestoreSettingsVS3V02.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set VS3_BACKUP, 0xD3002780 +.set VS3_BACKUP, 0xD3003500 RestoreSettingsVS: lis %r3, VS3_BACKUP@h diff --git a/kernel/asm/RestoreSettingsVS4EXP.S b/kernel/asm/RestoreSettingsVS4EXP.S index 4e93b57..a2f0cd2 100644 --- a/kernel/asm/RestoreSettingsVS4EXP.S +++ b/kernel/asm/RestoreSettingsVS4EXP.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set VS4_BACKUP, 0xD3002780 +.set VS4_BACKUP, 0xD3003500 RestoreSettingsVS: lis %r3, VS4_BACKUP@h diff --git a/kernel/asm/RestoreSettingsVS4JAP.S b/kernel/asm/RestoreSettingsVS4JAP.S index cdf328b..c1d3577 100644 --- a/kernel/asm/RestoreSettingsVS4JAP.S +++ b/kernel/asm/RestoreSettingsVS4JAP.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set VS4_BACKUP, 0xD3002780 +.set VS4_BACKUP, 0xD3003500 RestoreSettingsVS: lis %r3, VS4_BACKUP@h diff --git a/kernel/asm/RestoreSettingsVS4V06EXP.S b/kernel/asm/RestoreSettingsVS4V06EXP.S index 5dbb546..59efa19 100644 --- a/kernel/asm/RestoreSettingsVS4V06EXP.S +++ b/kernel/asm/RestoreSettingsVS4V06EXP.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set VS4_BACKUP, 0xD3002780 +.set VS4_BACKUP, 0xD3003500 RestoreSettingsVS: lis %r3, VS4_BACKUP@h diff --git a/kernel/asm/RestoreSettingsVS4V06JAP.S b/kernel/asm/RestoreSettingsVS4V06JAP.S index 2852e0e..2edc3d5 100644 --- a/kernel/asm/RestoreSettingsVS4V06JAP.S +++ b/kernel/asm/RestoreSettingsVS4V06JAP.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set VS4_BACKUP, 0xD3002780 +.set VS4_BACKUP, 0xD3003500 RestoreSettingsVS: lis %r3, VS4_BACKUP@h diff --git a/kernel/asm/RestoreSettingsYAKRVB.S b/kernel/asm/RestoreSettingsYAKRVB.S index 012b587..293a7a7 100644 --- a/kernel/asm/RestoreSettingsYAKRVB.S +++ b/kernel/asm/RestoreSettingsYAKRVB.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set YAK_BACKUP, (0xD3002780+0xE8) +.set YAK_BACKUP, (0xD3003500+0xE8) .set YAK_DEST, (0x803D3D0C+0xE8) RestoreSettingsYAKRVB: diff --git a/kernel/asm/RestoreSettingsYAKRVC.S b/kernel/asm/RestoreSettingsYAKRVC.S index a63f35c..b250ddc 100644 --- a/kernel/asm/RestoreSettingsYAKRVC.S +++ b/kernel/asm/RestoreSettingsYAKRVC.S @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -.set YAK_BACKUP, (0xD3002780+0xE8) +.set YAK_BACKUP, (0xD3003500+0xE8) .set YAK_DEST, (0x803D67AC+0xE8) RestoreSettingsYAKRVB: diff --git a/kernel/asm/SIInitStore.S b/kernel/asm/SIInitStore.S index 9bf4a36..609ced7 100644 --- a/kernel/asm/SIInitStore.S +++ b/kernel/asm/SIInitStore.S @@ -1,6 +1,6 @@ #include -.set SI_INITED, 0x93002740 +.set SI_INITED, 0x93003060 SIInitStore: lis %r5, SI_INITED@h diff --git a/kernel/main.c b/kernel/main.c index 2da8532..3c2a2f7 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -66,6 +66,7 @@ u32 virtentry = 0; u32 drcAddress = 0; u32 drcAddressAligned = 0; bool isWiiVC = false; +bool wiiVCInternal = false; int _main( int argc, char *argv[] ) { //BSS is in DATA section so IOS doesnt touch it, we need to manually clear it @@ -156,8 +157,12 @@ int _main( int argc, char *argv[] ) //Verification if we can read from disc if(memcmp(ConfigGetGamePath(), "di", 3) == 0) - RealDI_Init(); //will shutdown on fail - + { + if(isWiiVC) //will be inited later + wiiVCInternal = true; + else //will shutdown on fail + RealDI_Init(); + } BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); @@ -211,8 +216,8 @@ int _main( int argc, char *argv[] ) memset32((void*)RESET_STATUS, 0, 0x20); sync_after_write((void*)RESET_STATUS, 0x20); - memset32((void*)0x13002800, 0, 0x30); - sync_after_write((void*)0x13002800, 0x30); + memset32((void*)0x13003100, 0, 0x30); + sync_after_write((void*)0x13003100, 0x30); memset32((void*)0x13160000, 0, 0x20); sync_after_write((void*)0x13160000, 0x20); diff --git a/kernel/wdvd.c b/kernel/wdvd.c index ac6a5e3..e6b4b01 100644 --- a/kernel/wdvd.c +++ b/kernel/wdvd.c @@ -151,21 +151,26 @@ int WDVD_FST_Close() return 0; } -static s32 _WDVD_FST_Seek( s32 pos ) +static char *discName[2] = { "game.iso", "disc2.iso" }; +int WDVD_FST_OpenDisc(u32 discNum) { - //gprintf("_FST_seek_r()\n" ); + if(discNum > 1) return -1; + return WDVD_FST_Open(discName[discNum]); +} - if( pos < 0 || pos > fst[ openFile.entry ].filelen ) +u32 WDVD_FST_LSeek( u32 pos ) +{ + if( pos > fst[ openFile.entry ].filelen ) { //gprintf("seek: shit\n"); - return -1; + pos = fst[ openFile.entry ].filelen; } openFile.offset = pos; return pos; } -int WDVD_FST_Read(u8 *ptr, s32 pos, s32 len) +int WDVD_FST_Read(u8 *ptr, s32 len) { //gprintf("read( %d )\n", fd ); if( !openFile.inUse ) @@ -173,11 +178,6 @@ int WDVD_FST_Read(u8 *ptr, s32 pos, s32 len) //gprintf("read: !openFile.inUse\n"); return -1; } - if( _WDVD_FST_Seek(pos) < 0) - { - //gprintf("read: _FST_Seek < 0\n"); - return 0; - } if( openFile.offset >= fst[ openFile.entry ].filelen ) { //gprintf("read: 2\n"); @@ -202,7 +202,6 @@ int WDVD_FST_Read(u8 *ptr, s32 pos, s32 len) openFile.offset += len; return len; - } static bool read_disc() { @@ -310,7 +309,6 @@ bool WDVD_FST_Unmount() static u32 inbuf[ 8 ] ALIGNED( 32 ); static u32 outbuf[ 8 ] ALIGNED( 32 ); -static u32 tmpbuf[ 8 ] ALIGNED( 32 ); static const char di_fs[] ALIGNED( 32 ) = "/dev/di"; static s32 di_fd = -1; diff --git a/kernel/wdvd.h b/kernel/wdvd.h index 1699a6e..89f3868 100644 --- a/kernel/wdvd.h +++ b/kernel/wdvd.h @@ -9,7 +9,9 @@ s32 WDVD_GetHandle(); bool WDVD_FST_IsMounted(); bool WDVD_FST_Mount(); int WDVD_FST_Open(const char *path); -int WDVD_FST_Read(u8 *ptr, s32 pos, s32 len); +int WDVD_FST_OpenDisc(u32 discNum); +u32 WDVD_FST_LSeek(u32 pos); +int WDVD_FST_Read(u8 *ptr, s32 len); int WDVD_FST_Close(); bool WDVD_FST_Unmount(); diff --git a/loader/include/dip.h b/loader/include/dip.h index 995cd8b..6196558 100644 --- a/loader/include/dip.h +++ b/loader/include/dip.h @@ -63,7 +63,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define DIP_IMM (DIP_BASE+0x20) #define DIP_CONFIG (DIP_BASE+0x24) -#define DIP_CMD_WIIVC 0x71 #define DIP_CMD_NORMAL 0xA8 #define DIP_CMD_DVDR 0xD0 diff --git a/loader/include/wdvd.h b/loader/include/wdvd.h index 10b5b91..0fae939 100644 --- a/loader/include/wdvd.h +++ b/loader/include/wdvd.h @@ -23,10 +23,15 @@ bool WDVD_IsPartitionOpen(); bool WDVD_FST_IsMounted(); bool WDVD_FST_Mount(); int WDVD_FST_Open(const char *path); -int WDVD_FST_Read(u8 *ptr, off_t pos, size_t len); +int WDVD_FST_OpenDisc(u32 discNum); +u32 WDVD_FST_LSeek(u32 pos); +int WDVD_FST_Read(u8 *ptr, s32 len); int WDVD_FST_Close(); bool WDVD_FST_Unmount(); +//aligned for smaller reads under 0x20 +extern u8 wdvdTmpBuf[]; + #ifdef __cplusplus } #endif diff --git a/loader/loader.dol b/loader/loader.dol index d86e233..e0720f0 100644 Binary files a/loader/loader.dol and b/loader/loader.dol differ diff --git a/loader/source/FPad.c b/loader/source/FPad.c index 92b8f83..b467923 100644 --- a/loader/source/FPad.c +++ b/loader/source/FPad.c @@ -53,11 +53,13 @@ static u32 (*const PADRead)(u32) = (void*)0x93000000; #define C_NOT_SET (0<<0) void FPAD_Init( void ) { - DCInvalidateRange((void*)0x93000000, 0x2900); + DCInvalidateRange((void*)0x93000000, 0x3000); memcpy((void*)0x93000000, PADReadGC_bin, PADReadGC_bin_size); - memset((void*)0x93002700, 0, 0x200); //clears alot of pad stuff - DCFlushRange((void*)0x93000000, 0x2900); - ICInvalidateRange((void*)0x93000000, 0x2700); + DCFlushRange((void*)0x93000000, 0x3000); + ICInvalidateRange((void*)0x93000000, 0x3000); + DCInvalidateRange((void*)0x93003010, 0x190); + memset((void*)0x93003010, 0, 0x190); //clears alot of pad stuff + DCFlushRange((void*)0x93003010, 0x190); struct BTPadCont *BTPad = (struct BTPadCont*)0x932F0000; u32 i; for(i = 0; i < WPAD_MAX_WIIMOTES; ++i) @@ -116,7 +118,7 @@ void FPAD_Update( void ) /* HID */ HIDUpdateRegisters(); PADRead(0); - PADStatus *Pad = (PADStatus*)(0x93002800); + PADStatus *Pad = (PADStatus*)(0x93003100); for(i = 0; i < PAD_CHANMAX; ++i) { PAD_Pressed |= Pad[i].button; diff --git a/loader/source/Patches.c b/loader/source/Patches.c index 8b933e8..9009e13 100644 --- a/loader/source/Patches.c +++ b/loader/source/Patches.c @@ -282,13 +282,10 @@ int LoadKernel(void) gprintf("IOS Version: 0x%08X\n", FoundVersion); DCFlushRange(IOSVersion, 0x20); - //char Path[32]; - char *const Path = (char*)0x93003020; - DCInvalidateRange(Path, 1024); - memset(Path, 0, 1024); - snprintf(Path, 1024, "/shared1/%.8s.app", Entry); + char Path[32]; + snprintf(Path, 32, "/shared1/%.8s.app", Entry); gprintf("Kernel:\"%s\"\r\n", Path ); - DCFlushRange(Path, 1024); + DCFlushRange(Path, 32); // Open the actual IOS58 kernel file. int kfd = IOS_Open(Path, 1); diff --git a/loader/source/TRI.c b/loader/source/TRI.c index 9b716fa..760addb 100644 --- a/loader/source/TRI.c +++ b/loader/source/TRI.c @@ -41,22 +41,25 @@ static const char SETTINGS_VS4EXP[] = "/saves/VS4EXPsettings.bin"; static const char SETTINGS_VS4V06JAP[] = "/saves/VS4V06JAPsettings.bin"; static const char SETTINGS_VS4V06EXP[] = "/saves/VS4V06EXPsettings.bin"; +extern bool wiiVCInternal; + static u32 DOLRead32(u32 loc, u32 DOLOffset, FIL *f, u32 CurDICMD) { u32 BufAtOffset = 0; - if(f != NULL) + if(wiiVCInternal) + { + WDVD_FST_LSeek(DOLOffset+loc); + WDVD_FST_Read(wdvdTmpBuf, 4); + memcpy(&BufAtOffset, wdvdTmpBuf, 4); + } + else if(f != NULL) { UINT read; f_lseek(f, DOLOffset+loc); f_read(f, &BufAtOffset, 4, &read); } else if(CurDICMD) - { - if(CurDICMD == DIP_CMD_WIIVC) - WDVD_FST_Read((u8*)&BufAtOffset, DOLOffset+loc, 4); - else - ReadRealDisc((u8*)&BufAtOffset, DOLOffset+loc, 4, CurDICMD); - } + ReadRealDisc((u8*)&BufAtOffset, DOLOffset+loc, 4, CurDICMD); return BufAtOffset; } @@ -71,10 +74,15 @@ u32 TRISetupGames(char *Path, u32 CurDICMD, u32 ISOShift) if(CurDICMD) { - if(CurDICMD == DIP_CMD_WIIVC) - WDVD_FST_Read((u8*)&DOLOffset, 0x420+ISOShift, 4); - else - ReadRealDisc((u8*)&DOLOffset, 0x420+ISOShift, 4, CurDICMD); + ReadRealDisc((u8*)&DOLOffset, 0x420+ISOShift, 4, CurDICMD); + DOLOffset+=ISOShift; + } + else if(wiiVCInternal) + { + WDVD_FST_OpenDisc(0); + WDVD_FST_LSeek(0x420+ISOShift); + WDVD_FST_Read(wdvdTmpBuf, 4); + memcpy(&DOLOffset, wdvdTmpBuf, 4); DOLOffset+=ISOShift; } else @@ -214,7 +222,9 @@ u32 TRISetupGames(char *Path, u32 CurDICMD, u32 ISOShift) CreateNewFile(SaveFile, 0x100); } - if (fres == FR_OK) + if(wiiVCInternal) + WDVD_FST_Close(); + else if (fres == FR_OK) f_close(&f); return res; } diff --git a/loader/source/global.c b/loader/source/global.c index deb18b3..e99929e 100644 --- a/loader/source/global.c +++ b/loader/source/global.c @@ -54,7 +54,7 @@ static int bg_xPos = 0; u32 POffset; -NIN_CFG* ncfg = (NIN_CFG*)0x93002900; +NIN_CFG* ncfg = (NIN_CFG*)0x93004000; bool UseSD; const char* const GetRootDevice() diff --git a/loader/source/main.c b/loader/source/main.c index 634c0b2..6752c4d 100644 --- a/loader/source/main.c +++ b/loader/source/main.c @@ -124,6 +124,9 @@ static ioctlv IOCTL_Buf ALIGNED(32); static const char ARGSBOOT_STR[9] ALIGNED(0x10) = {'a','r','g','s','b','o','o','t','\0'}; //makes it easier to go through the file static const char NIN_BUILD_STRING[] ALIGNED(32) = NIN_VERSION_STRING; // Version detection string used by nintendont launchers "$$Version:x.xxx" +bool isWiiVC = false; +bool wiiVCInternal = false; + /** * Update meta.xml. */ @@ -230,28 +233,40 @@ static u32 CheckForMultiGameAndRegion(u32 CurDICMD, u32 *ISOShift, u32 *BI2regio FRESULT fres = FR_DISK_ERR; if(CurDICMD) + ReadRealDisc(MultiHdr, 0, 0x800, CurDICMD); + else if (IsSupportedFileExt(ncfg->GamePath) || wiiVCInternal) { - if(CurDICMD == DIP_CMD_WIIVC) - WDVD_FST_Read(MultiHdr, 0, 0x800); - else - ReadRealDisc(MultiHdr, 0, 0x800, CurDICMD); - } - else if (IsSupportedFileExt(ncfg->GamePath)) - { - snprintf(GamePath, sizeof(GamePath), "%s:%s", GetRootDevice(), ncfg->GamePath); - fres = f_open_char(&f, GamePath, FA_READ|FA_OPEN_EXISTING); - if (fres != FR_OK) + if(wiiVCInternal) { - // Error opening the file. - free(MultiHdr); - return -1; + if(WDVD_FST_OpenDisc(0) != 0) + { + // Error opening the file. + free(MultiHdr); + return -1; + } } - - f_read(&f, MultiHdr, 0x800, &read); + else + { + snprintf(GamePath, sizeof(GamePath), "%s:%s", GetRootDevice(), ncfg->GamePath); + fres = f_open_char(&f, GamePath, FA_READ|FA_OPEN_EXISTING); + if (fres != FR_OK) + { + // Error opening the file. + free(MultiHdr); + return -1; + } + } + if(wiiVCInternal) + read = WDVD_FST_Read(MultiHdr, 0x800); + else + f_read(&f, MultiHdr, 0x800, &read); if (read != 0x800) { // Error reading from the file. - f_close(&f); + if(wiiVCInternal) + WDVD_FST_Close(); + else + f_close(&f); free(MultiHdr); return -2; } @@ -271,16 +286,27 @@ static u32 CheckForMultiGameAndRegion(u32 CurDICMD, u32 *ISOShift, u32 *BI2regio *ISOShift = 0; if (BI2region) { - f_lseek(&f, 0x8458); - f_read(&f, BI2region, sizeof(*BI2region), &read); + if(wiiVCInternal) + { + WDVD_FST_LSeek(0x8458); + read = WDVD_FST_Read(wdvdTmpBuf, sizeof(*BI2region)); + memcpy(&BI2region, wdvdTmpBuf, sizeof(*BI2region)); + } + else + { + f_lseek(&f, 0x8458); + f_read(&f, BI2region, sizeof(*BI2region), &read); + } if (read != sizeof(*BI2region)) { // Error reading from the file. ret = -3; } } - - f_close(&f); + if(wiiVCInternal) + WDVD_FST_Close(); + else + f_close(&f); free(MultiHdr); return ret; } @@ -331,7 +357,10 @@ static u32 CheckForMultiGameAndRegion(u32 CurDICMD, u32 *ISOShift, u32 *BI2regio if (!CurDICMD) { // Close the disc image file. - f_close(&f); + if(wiiVCInternal) + WDVD_FST_Close(); + else + f_close(&f); } if (BI2region) @@ -387,16 +416,19 @@ static u32 CheckForMultiGameAndRegion(u32 CurDICMD, u32 *ISOShift, u32 *BI2regio } if(CurDICMD) - { - if(CurDICMD == DIP_CMD_WIIVC) - WDVD_FST_Read(GameHdr, RealOffset, 0x800); - else - ReadRealDisc(GameHdr, RealOffset, 0x800, CurDICMD); - } + ReadRealDisc(GameHdr, RealOffset, 0x800, CurDICMD); else { - f_lseek(&f, RealOffset); - f_read(&f, GameHdr, 0x800, &read); + if(wiiVCInternal) + { + WDVD_FST_LSeek(RealOffset); + read = WDVD_FST_Read(GameHdr, 0x800); + } + else + { + f_lseek(&f, RealOffset); + f_read(&f, GameHdr, 0x800, &read); + } } // Make sure the title in the header is NULL terminated. @@ -420,7 +452,10 @@ static u32 CheckForMultiGameAndRegion(u32 CurDICMD, u32 *ISOShift, u32 *BI2regio free(MultiHdr); if (!CurDICMD) { - f_close(&f); + if(wiiVCInternal) + WDVD_FST_Close(); + else + f_close(&f); } // TODO: Share code with menu.c. @@ -512,9 +547,9 @@ static u32 CheckForMultiGameAndRegion(u32 CurDICMD, u32 *ISOShift, u32 *BI2regio memcpy(&ncfg->GameID, gi[PosX].ID, 4); return 0; } + static char dev_es[] ATTRIBUTE_ALIGN(32) = "/dev/es"; -bool isWiiVC = false; extern vu32 FoundVersion; int main(int argc, char **argv) { @@ -818,22 +853,28 @@ int main(int argc, char **argv) ShowMessageScreenAndExit("Found no Partition on Wii VC Disc!", 1); if(!WDVD_FST_Mount()) ShowMessageScreenAndExit("Unable to open Partition on Wii VC Disc!", 1); - if(WDVD_FST_Open("game.iso") != 0) + if(WDVD_FST_OpenDisc(0) != 0) ShowMessageScreenAndExit("No game.iso on Wii VC Disc!", 1); u8 *DIBuf = memalign(32,0x800); - if(WDVD_FST_Read(DIBuf, 0, 0x800) != 0x800) + if(WDVD_FST_Read(DIBuf, 0x800) != 0x800) { free(DIBuf); ShowMessageScreenAndExit("Cant read game.iso start!", 1); } if( IsGCGame(DIBuf) == false ) { - free(DIBuf); - ShowMessageScreenAndExit("game.iso is not a GC Disc!", 1); + WDVD_FST_LSeek(0x8000); + WDVD_FST_Read(DIBuf, 0x800); + if( IsGCGame(DIBuf) == false ) + { + free(DIBuf); + ShowMessageScreenAndExit("game.iso is not a GC Disc!", 1); + } } memcpy(&(ncfg->GameID), DIBuf, 4); free(DIBuf); - CurDICMD = DIP_CMD_WIIVC; + WDVD_FST_Close(); + wiiVCInternal = true; } else { @@ -1094,9 +1135,8 @@ int main(int argc, char **argv) WUPC_Shutdown(); WPAD_Shutdown(); - if(CurDICMD == DIP_CMD_WIIVC) + if(wiiVCInternal) { - WDVD_FST_Close(); WDVD_FST_Unmount(); WDVD_Close(); } @@ -1418,10 +1458,6 @@ int main(int argc, char **argv) VIDEO_WaitVSync(); GX_AbortFrame(); - DCInvalidateRange((void*)0x93000000, 0x3000); - memset((void*)0x93002700, 0, 0x200); //clears alot of pad stuff - memset((void*)0x93002C00, 0, 0x400); //clears alot of multidol stuff - strcpy((char*)0x930028A0, "ARStartDMA: %08x %08x %08x\n"); //ARStartDMA Debug DCFlushRange((void*)0x93000000, 0x3000); DCInvalidateRange((void*)0x93010010, 0x10000); @@ -1433,12 +1469,14 @@ int main(int argc, char **argv) memset((void*)0x93020000, 0, 0x10000); DCFlushRange((void*)0x93020000, 0x10000); - DCInvalidateRange((void*)0x93003000, 0x20); + DCInvalidateRange((void*)0x93003000, 0x200); //*(vu32*)0x93003000 = currev; //set kernel rev (now in LoadKernel) *(vu32*)0x93003008 = 0x80000004; //just some address for SIGetType //0x9300300C is already used for multi-iso - memset((void*)0x93003010, 0, 0x10); //disable rumble on bootup - DCFlushRange((void*)0x93003000, 0x20); + memset((void*)0x93003010, 0, 0x190); //clears alot of pad stuff + strcpy((char*)0x930031A0, "ARStartDMA: %08x %08x %08x\n"); //ARStartDMA Debug + memset((void*)0x930031E0, 0, 0x20); //clears tgc stuff + DCFlushRange((void*)0x93003000, 0x200); //lets prevent weird events __STM_Close(); diff --git a/loader/source/ppc/PADReadGC.c b/loader/source/ppc/PADReadGC.c index c9eff74..c00fccb 100644 --- a/loader/source/ppc/PADReadGC.c +++ b/loader/source/ppc/PADReadGC.c @@ -14,23 +14,21 @@ static vu32* const _siReg = (vu32*)0xCD006400; static vu32* const MotorCommand = (vu32*)0x93003010; static vu32* RESET_STATUS = (vu32*)0xD3003420; static vu32* HID_STATUS = (vu32*)0xD3003440; -static vu32* HIDMotor = (vu32*)0x93002700; -static vu32* PadUsed = (vu32*)0x93002704; +static vu32* HIDMotor = (vu32*)0x93003020; +static vu32* PadUsed = (vu32*)0x93003024; -static vu32* PADIsBarrel = (vu32*)0xD3002830; -static vu32* PADBarrelEnabled = (vu32*)0xD3002840; -static vu32* PADBarrelPress = (vu32*)0xD3002850; +static vu32* PADIsBarrel = (vu32*)0xD3003130; +static vu32* PADBarrelEnabled = (vu32*)0xD3003140; +static vu32* PADBarrelPress = (vu32*)0xD3003150; static volatile struct BTPadCont *BTPad = (volatile struct BTPadCont*)0x932F0000; -static vu32* BTMotor = (vu32*)0x93002720; -static vu32* BTPadFree = (vu32*)0x93002730; -static vu32* SIInited = (vu32*)0x93002740; -static vu32* PADSwitchRequired = (vu32*)0x93002744; -static vu32* PADForceConnected = (vu32*)0x93002748; -static vu32* drcAddress = (vu32*)0x9300274C; -static vu32* drcAddressAligned = (vu32*)0x93002750; -//fw.img r590 pointer to state TODO make dynamic -static vu32* drcState = (vu32*)0x938BD770; +static vu32* BTMotor = (vu32*)0x93003040; +static vu32* BTPadFree = (vu32*)0x93003050; +static vu32* SIInited = (vu32*)0x93003060; +static vu32* PADSwitchRequired = (vu32*)0x93003064; +static vu32* PADForceConnected = (vu32*)0x93003068; +static vu32* drcAddress = (vu32*)0x9300306C; +static vu32* drcAddressAligned = (vu32*)0x93003070; static u32 PrevAdapterChannel1 = 0; static u32 PrevAdapterChannel2 = 0; @@ -38,6 +36,7 @@ static u32 PrevAdapterChannel3 = 0; static u32 PrevAdapterChannel4 = 0; const s8 DEADZONE = 0x1A; + #define HID_PAD_NONE 4 #define HID_PAD_NOT_SET 0xFF @@ -81,6 +80,16 @@ const s8 DEADZONE = 0x1A; ); \ } +#define DRC_DEADZONE 10 +#define _DRC_BUILD_TMPSTICK(inval) \ + tmp_stick16 = (((s8)(inval-0x80))*13)>>3; \ + if(tmp_stick16 > DRC_DEADZONE) tmp_stick16 = (tmp_stick16-DRC_DEADZONE)*1.08f; \ + else if(tmp_stick16 < -DRC_DEADZONE) tmp_stick16 = (tmp_stick16+DRC_DEADZONE)*1.08f; \ + else tmp_stick16 = 0; \ + if(tmp_stick16 > 0x7F) tmp_stick8 = 0x7F; \ + else if(tmp_stick16 < -0x80) tmp_stick8 = -0x80; \ + else tmp_stick8 = (s8)tmp_stick16; + u32 _start(u32 calledByGame) { // Registers r1,r13-r31 automatically restored if used. @@ -89,11 +98,11 @@ u32 _start(u32 calledByGame) u32 Rumble = 0, memInvalidate, memFlush; u32 used = 0; - PADStatus *Pad = (PADStatus*)(0x93002800); //PadBuff + PADStatus *Pad = (PADStatus*)(0x93003100); //PadBuff u32 MaxPads; if(calledByGame) { - MaxPads = ((NIN_CFG*)0x93002900)->MaxPads; + MaxPads = ((NIN_CFG*)0x93004000)->MaxPads; if (MaxPads > NIN_CFG_MAXPAD) MaxPads = NIN_CFG_MAXPAD; } @@ -107,7 +116,7 @@ u32 _start(u32 calledByGame) asm volatile("dcbi 0,%0; sync" : : "b"(memInvalidate) : "memory"); /* For Wii VC */ - if(calledByGame && *drcAddress && *drcState) + if(calledByGame && *drcAddress) { used |= (1<<0); //always use channel 0 if(HIDPad == HID_PAD_NOT_SET) @@ -170,32 +179,16 @@ u32 _start(u32 calledByGame) } else /* for held status */ *RESET_STATUS = 0; - //scale sticks next - s16 leftX = (((s8)(i2cdata[4]-0x80))*13)>>3; - s16 leftY = (((s8)(i2cdata[5]-0x80))*13)>>3; - s16 rightX = (((s8)(i2cdata[6]-0x80))*13)>>3; - s16 rightY = (((s8)(i2cdata[7]-0x80))*13)>>3; - s8 tmp_stick; - //clamp left X - if(leftX > 0x7F) tmp_stick = 0x7F; - else if(leftX < -0x80) tmp_stick = -0x80; - else tmp_stick = leftX; - Pad[0].stickX = tmp_stick; - //clamp left Y - if(leftY > 0x7F) tmp_stick = 0x7F; - else if(leftY < -0x80) tmp_stick = -0x80; - else tmp_stick = leftY; - Pad[0].stickY = tmp_stick; - //clamp right X - if(rightX > 0x7F) tmp_stick = 0x7F; - else if(rightX < -0x80) tmp_stick = -0x80; - else tmp_stick = rightX; - Pad[0].substickX = tmp_stick; - //clamp right Y - if(rightY > 0x7F) tmp_stick = 0x7F; - else if(rightY < -0x80) tmp_stick = -0x80; - else tmp_stick = rightY; - Pad[0].substickY = tmp_stick; + //do scale, deadzone and clamp + s8 tmp_stick8; s16 tmp_stick16; + _DRC_BUILD_TMPSTICK(i2cdata[4]); + Pad[0].stickX = tmp_stick8; + _DRC_BUILD_TMPSTICK(i2cdata[5]); + Pad[0].stickY = tmp_stick8; + _DRC_BUILD_TMPSTICK(i2cdata[6]); + Pad[0].substickX = tmp_stick8; + _DRC_BUILD_TMPSTICK(i2cdata[7]); + Pad[0].substickY = tmp_stick8; } else { diff --git a/loader/source/wdvd.c b/loader/source/wdvd.c index 4d5db53..e68c52a 100644 --- a/loader/source/wdvd.c +++ b/loader/source/wdvd.c @@ -13,6 +13,9 @@ #define SECTOR_SIZE 0x800 +//aligned for smaller reads under 0x20 +u8 wdvdTmpBuf[0x20] ATTRIBUTE_ALIGN(32); + typedef struct { u32 dol_offset; u32 fst_offset; @@ -150,21 +153,26 @@ int WDVD_FST_Close() return 0; } -static off_t _WDVD_FST_Seek( off_t pos ) +static char *discName[2] = { "game.iso", "disc2.iso" }; +int WDVD_FST_OpenDisc(u32 discNum) { - //gprintf("_FST_seek_r()\n" ); + if(discNum > 1) return -1; + return WDVD_FST_Open(discName[discNum]); +} - if( pos < 0 || pos > fst[ openFile.entry ].filelen ) +u32 WDVD_FST_LSeek( u32 pos ) +{ + if( pos > fst[ openFile.entry ].filelen ) { //gprintf("seek: shit\n"); - return -1; + pos = fst[ openFile.entry ].filelen; } openFile.offset = pos; return pos; } -int WDVD_FST_Read(u8 *ptr, off_t pos, size_t len) +int WDVD_FST_Read(u8 *ptr, s32 len) { //gprintf("read( %d )\n", fd ); if( !openFile.inUse ) @@ -172,11 +180,6 @@ int WDVD_FST_Read(u8 *ptr, off_t pos, size_t len) //gprintf("read: !openFile.inUse\n"); return -1; } - if( _WDVD_FST_Seek(pos) < 0) - { - //gprintf("read: _FST_Seek < 0\n"); - return 0; - } if( openFile.offset >= fst[ openFile.entry ].filelen ) { //gprintf("read: 2\n"); @@ -201,7 +204,6 @@ int WDVD_FST_Read(u8 *ptr, off_t pos, size_t len) openFile.offset += len; return len; - } static bool read_disc() { diff --git a/mem_map.txt b/mem_map.txt index a9e25c7..f7dbe1d 100644 --- a/mem_map.txt +++ b/mem_map.txt @@ -14,23 +14,7 @@ MEM2 0x92F00000-0x93000000=Nintendont kernel -0x93000000-0x93001000=padread gc bin -0x93001000-0x93002700=old padread hid bin -0x93002700=padread hid motor -0x93002704=padread game setting -0x93002720-0x93002730=padread bt motor -0x93002730-0x93002740=padread bt channel free -0x93002740-0x93002744=SIInited -0x93002800-0x93002830=PadBuff - -0x93002830-0x93002890=pad barrel stuff -0x93002894=clear mem pos -0x93002898=clear mem size -0x930028a0-0x930028c0=ARStartDMA Debug str - -0x93002900-0x93002B20=nincfg - -0x93002EE0-0x93003000=tgc dol header +0x93000000-0x93003000=padread gc bin 0x93003000=ios58 rev 0x93003004=hid thread status @@ -42,7 +26,18 @@ MEM2 0x93003018=pad rumble command chan2 0x9300301C=pad rumble command chan3 -0x93003020-0x93003420=ios58 kernel path +0x93003020=padread hid motor +0x93003024=padread game setting +0x93003040-0x93003050=padread bt motor +0x93003050-0x93003060=padread bt channel free +0x93003060-0x93003064=SIInited +0x93003080-0x93003084=Triforce In Testmenu +0x93003100-0x93003130=PadBuff + +0x93003130-0x93003190=pad barrel stuff +0x930031a0-0x930031c0=ARStartDMA Debug str + +0x930031E0-0x93003200=tgc dol header 0x93003420=reset status 0x93003424=dol flush len @@ -51,6 +46,9 @@ MEM2 0x93003440=hid load request 0x93003460=hid controller ini +0x93003500-0x93003600=Triforce game settings +0x93004000-0x93005000=nincfg + 0x93005000-0x930050E8=hid controller positions 0x930050F0-0x93005170=hid packet (may be bigger device dependent) diff --git a/multidol/apploader.c b/multidol/apploader.c index 020ef02..ed3a3f4 100644 --- a/multidol/apploader.c +++ b/multidol/apploader.c @@ -27,7 +27,7 @@ typedef void *(*app_final)(); typedef void (*app_entry)(void (**init)(int (*report)(const char *fmt, ...)), int (**main)(), void *(**final)()); static u8 *appldr = (u8*)0x81200000; -static struct _TGCInfo *TGCInfo = (struct _TGCInfo*)0x93002FE0; +static struct _TGCInfo *TGCInfo = (struct _TGCInfo*)0x930031E0; #define APPLDR_OFFSET 0x2440 #define APPLDR_CODE 0x2460