mirror of
https://github.com/project-slippi/Nintendont.git
synced 2025-10-06 00:22:40 +02:00
-completely restructured how internal wii vc titles get read in, again hopefully it didnt break anything
134 lines
3.7 KiB
C
134 lines
3.7 KiB
C
/*
|
|
apploader.c for Nintendont (Loader)
|
|
|
|
Copyright (C) 2014 FIX94
|
|
|
|
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 "cache.h"
|
|
#include "utils.h"
|
|
#include "apploader.h"
|
|
#include "dip.h"
|
|
|
|
typedef int (*app_main)(char **dst, u32 *size, u32 *offset);
|
|
typedef void (*app_init)(int (*report)(const char *fmt, ...));
|
|
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*)0x930031E0;
|
|
|
|
#define APPLDR_OFFSET 0x2440
|
|
#define APPLDR_CODE 0x2460
|
|
|
|
static int noprintf( const char *str, ... ) { return 0; };
|
|
|
|
void PrepareTGC(u32 Offset)
|
|
{
|
|
if(TGCInfo->isTGC == 0)
|
|
return;
|
|
|
|
if(Offset == TGCInfo->doloffset || Offset == TGCInfo->fstoffset)
|
|
TGCInfo->tgcoffset = 0; /* we can stop the manual offset correction */
|
|
}
|
|
|
|
void ParseTGC(char *Data, u32 Length, u32 Offset)
|
|
{
|
|
if(TGCInfo->isTGC == 0)
|
|
return;
|
|
|
|
if(Offset == 0x420) /* update internal gcm header with the tgc header */
|
|
{
|
|
*(vu32*)(Data+0x00) = TGCInfo->doloffset;
|
|
*(vu32*)(Data+0x04) = TGCInfo->fstoffset;
|
|
*(vu32*)(Data+0x08) = TGCInfo->fstsize;
|
|
*(vu32*)(Data+0x0C) = TGCInfo->fstsize;
|
|
*(vu32*)(Data+0x34) = TGCInfo->userpos;
|
|
*(vu32*)(Data+0x38) = 0x57058000L - (TGCInfo->userpos);
|
|
sync_after_write(Data, Length);
|
|
}
|
|
else if(Offset == TGCInfo->fstoffset) /* update internal gcm fst with correct tgc positions */
|
|
{
|
|
char *FSTable = Data;
|
|
u32 FSTEnt = *(u32*)(FSTable+0x08);
|
|
FST *fst = (FST *)(FSTable);
|
|
u32 i;
|
|
for(i = 1; i < FSTEnt; ++i)
|
|
{
|
|
if(fst[i].Type == 0) /* update file offset */
|
|
fst[i].FileOffset -= TGCInfo->fstupdate;
|
|
}
|
|
sync_after_write(Data, Length);
|
|
}
|
|
}
|
|
|
|
/* Thanks Tinyload */
|
|
static struct
|
|
{
|
|
char revision[16];
|
|
void *entry;
|
|
s32 size;
|
|
s32 trailersize;
|
|
s32 padding;
|
|
} apploader_hdr ALIGNED(32);
|
|
|
|
u32 Apploader_Run()
|
|
{
|
|
app_entry appldr_entry;
|
|
app_init appldr_init;
|
|
app_main appldr_main;
|
|
app_final appldr_final;
|
|
|
|
char *dst;
|
|
u32 len, offset;
|
|
|
|
sync_before_read(TGCInfo, sizeof(struct _TGCInfo));
|
|
|
|
/* Read apploader header */
|
|
DVDLowRead(&apploader_hdr, 0x20, TGCInfo->tgcoffset + APPLDR_OFFSET);
|
|
|
|
/* Calculate apploader length */
|
|
u32 appldr_len = apploader_hdr.size + apploader_hdr.trailersize;
|
|
|
|
/* Read apploader code */
|
|
DVDLowRead(appldr, appldr_len, TGCInfo->tgcoffset + APPLDR_CODE);
|
|
|
|
/* Flush into memory */
|
|
sync_before_exec(appldr, appldr_len);
|
|
|
|
/* Set basic information */
|
|
*(vu32*)0x800000F8 = 243000000; // Bus Clock Speed
|
|
*(vu32*)0x800000FC = 729000000; // CPU Clock Speed
|
|
|
|
/* Set apploader entry function */
|
|
appldr_entry = apploader_hdr.entry;
|
|
|
|
/* Call apploader entry */
|
|
appldr_entry(&appldr_init, &appldr_main, &appldr_final);
|
|
|
|
/* Initialize apploader */
|
|
appldr_init(noprintf);
|
|
|
|
while(appldr_main(&dst, &len, &offset))
|
|
{
|
|
/* Read data from DVD */
|
|
PrepareTGC( offset );
|
|
DVDLowRead( dst, len, offset + TGCInfo->tgcoffset );
|
|
ParseTGC( dst, len, offset );
|
|
}
|
|
|
|
/* Set entry point from apploader */
|
|
return (u32)appldr_final();
|
|
}
|