Delink/begin decompiling entry point

That is, xapi0.obj, which has been renamed from crt0.obj because it
appears to be part of the Xbox libraries rather than the C runtime.
This commit is contained in:
KeybadeBlox 2026-02-20 21:50:00 -05:00
parent 9b6c91a12e
commit 9cfd8b5bf3
7 changed files with 103 additions and 41 deletions

View file

@ -0,0 +1,83 @@
/* JSRF Decompilation: XDK/Xapi/xapi0.c
Entrypoint for Xbox programs.
Awkwardly, the placement in the .xbe suggests this is not part of the C runtime
(which is normally what provides mainCRTStartup()), but rather part of Xapi.
It's been named xapi0 in analogy to crt0 in a C runtime.
*/
#include "../CRT/stddef.h"
#include "../Win32.h"
// Things that should get declared in a header somewhere
#define XLD_LAUNCH_DASHBOARD_ERROR 1
#define XLD_ERROR_INVALID_XBE 1
extern struct IMAGE_TLS_DIRECTORY {
DWORD StartAddressOfRawData;
DWORD EndAddressOfRawData;
DWORD * AddressOfIndex;
void * AddressOfCallbacks;
DWORD SizeOfZeroFill;
DWORD Characteristics;
} _tls_used;
extern int XapiTlsSize;
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter);
BOOL __stdcall CloseHandle (HANDLE hHandle );
typedef DWORD (__stdcall * LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
HANDLE __stdcall CreateThread(
void * lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
PDWORD lpThreadId
);
void __stdcall XapiBootToDash(
DWORD dwReason,
DWORD dwParameter1,
DWORD dwParameter2
);
// Every program is supposed to have a main(), so we can just assume its
// existence with a declaration here
int main(void);
// Address: 0x00147FB4
// Status: unimplemented
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter) {
/* Runs some Xbox-specific initialization and then calls main() */
main();
return 0;
}
// Address: 0x00148023
// Status: nonmatching
void mainCRTStartup(void) {
/* The true entrypoint of the game, spawning a thread for the rest to run in
The linker automatically sets this function to the entrypoint.
*/
HANDLE thread;
// Figure out available thread-local storage
XapiTlsSize = (
(_tls_used.EndAddressOfRawData - _tls_used.StartAddressOfRawData) +
_tls_used.SizeOfZeroFill
) + 15 & 0xFFFFFFF0; // Round up to nearest 0x10
*_tls_used.AddressOfIndex = XapiTlsSize / (-4);
// Launch program as a thread
thread = CreateThread(NULL, 0, mainXapiStartup, NULL, 0, NULL);
// Boot back to dashboard with an error message if launching failed
if (thread == NULL)
XapiBootToDash(XLD_LAUNCH_DASHBOARD_ERROR, XLD_ERROR_INVALID_XBE, 0);
CloseHandle(thread);
}