PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
ExecPS2.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Licenced under Academic Free License version 2.0
7# Review ps2sdk README & LICENSE files for further details.
8*/
9
10#include <kernel.h>
11
12#include "ExecPS2.h"
13
14static int *p_ThreadID = (int *)0x800125EC; // Pointer to a variable containing the running thread's ID.
15static int *p_ThreadStatus = (int *)0x800125F4; // Pointer to a variable containing the running thread's status.
16static int (*p_CancelWakeupThread)(int ThreadID) = (void *)0x80004970;
17static int (*p_ChangeThreadPriority)(int ThreadID, int priority) = (void *)0x80004288;
18static int (*p_InitPgifHandler2)(void) = (void *)0x800021b0;
19static int (*p_InitSemaphores)(void) = (void *)0x80004e68;
20static int (*p_DeleteThread)(int thread_id) = (void *)0x80003f00;
21static int (*p_TerminateThread)(int ThreadID) = (void *)0x80003e00;
22static struct TCB *p_TCBs = (struct TCB *)0x80017400;
23static void (*p_InitializeINTC)(int interrupts) = (void *)0x8000b8d0;
24static void (*p_InitializeTIMER)(void) = (void *)0x8000b900;
25static void (*p_InitializeFPU)(void) = (void *)0x8000b7a8;
26static void (*p_InitializeScratchPad)(void) = (void *)0x8000b840;
27static int (*p_ResetEE)(int flags) = (void *)0x8000ad68;
28static void (*p_InitializeGS)(void) = (void *)0x8000aa60;
29static void (*p_SetGSCrt)(unsigned short int interlace, unsigned short int mode, unsigned short int ffmd) = (void *)0x8000a060;
30
31#ifndef REUSE_EXECPS2
32
33static void (*p_FlushDCache)(void) = (void *)0x80002a80;
34static void (*p_FlushICache)(void) = (void *)0x80002ac0;
35static char *(*p_eestrcpy)(char *dst, const char *src) = (void *)0x80005560;
36// static void *p_unk80012600 = (void *)0x80012600; // Not sure what this is, as it isn't used by the patch.
37static char *p_ArgsBuffer = (char *)0x80012608;
38
39#else
40
41static void *(*p_ExecPS2)(void *entry, void *gp, int argc, char *argv[]) = (void *)0x800057E8; // Not part of the SONY patch. See below.
42
43#endif
44
45// Taken from PCSX2's FPS2BIOS
46struct TCB
47{ // internal struct
48 struct TCB *next; //+00
49 struct TCB *prev; //+04
50 int status; //+08
51 void (*entry)(void *); //+0C
52 void *stack_res; //+10 initial $sp
53 void *gpReg; //+14
54 short currentPriority; //+18
55 short initPriority; //+1A
56 int waitSema, //+1C waitType?
57 semaId, //+20
58 wakeupCount, //+24
59 attr, //+28
60 option; //+2C
61 void (*entry_)(void *); //+30
62 int argc; //+34
63 char *argstring; //+38
64 void *stack; //+3C
65 int stackSize; //+40
66 int (*root)(); //+44
67 void *heap_base; //+48
68};
69
70static inline void SoftPeripheralEEReset(void)
71{
72 *(volatile unsigned int *)0x1000f000 = 4;
73 while (((*((volatile unsigned int *)0x1000f000)) & 4) == 0) {};
74 *(volatile unsigned int *)0x1000f000 = 4;
75
76 p_InitializeGS();
77 p_SetGSCrt(1, 2, 1); // Interlaced, NTSC, field mode.
78 p_InitializeINTC(0xdffd);
79 p_InitializeTIMER();
80 p_ResetEE(0x7F);
81 p_InitializeFPU();
82 p_InitializeScratchPad();
83}
84
85void *ExecPS2Patch(void *EntryPoint, void *gp, int argc, char *argv[])
86{
87 int i, CurrentThreadID;
88 struct TCB *tcb;
89#ifndef REUSE_EXECPS2
90 char *ArgsPtr;
91#endif
92
93 CurrentThreadID = *p_ThreadID;
94 p_CancelWakeupThread(CurrentThreadID);
95 p_ChangeThreadPriority(CurrentThreadID, 0);
96
97 // Like IOP kernels, the first thread is the idle thread.
98 for (i = 1, tcb = &p_TCBs[1]; i < MAX_THREADS; i++, tcb++) {
99 if (tcb->status != 0 && i != CurrentThreadID) {
100 if (tcb->status != THS_DORMANT)
101 p_TerminateThread(i);
102
103 p_DeleteThread(i);
104 }
105 }
106
107 p_InitSemaphores();
108 p_InitPgifHandler2();
109
110 *p_ThreadStatus = 0;
111 SoftPeripheralEEReset();
112
113#ifdef REUSE_EXECPS2
114 // Unlike the Sony patch, why don't we just reuse the original function in the kernel?
115 return p_ExecPS2(EntryPoint, gp, argc, argv);
116#else
117 for (i = 0, ArgsPtr = p_ArgsBuffer; i < argc; i++) {
118 ArgsPtr = p_eestrcpy(ArgsPtr, argv[i]);
119 }
120
121 tcb = &p_TCBs[CurrentThreadID];
122 tcb->argstring = p_ArgsBuffer;
123 tcb->argc = argc;
124 tcb->entry = EntryPoint;
125 tcb->entry_ = EntryPoint;
126 tcb->gpReg = gp;
127 tcb->initPriority = 0;
128 tcb->currentPriority = 0;
129 tcb->wakeupCount = 0;
130 tcb->waitSema = 0;
131 tcb->semaId = 0;
132
133 p_FlushICache();
134 p_FlushDCache();
135
136 return EntryPoint;
137#endif
138}
#define MAX_THREADS
Definition kernel.h:70
Definition ExecPS2.c:47