sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
libcdvd.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# (C) 2002 Nicholas Van Veen (nickvv@xtra.co.nz)
7# 2003 loser (loser@internalreality.com)
8# (c) 2004 Marcus R. Brown <mrbrown@0xd6.org>
9# Licenced under Academic Free License version 2.0
10# Review ps2sdk README & LICENSE files for further details.
11*/
12
22
23#include <stdio.h>
24#include <tamtypes.h>
25#include <kernel.h>
26#include <sifrpc.h>
27#include <string.h>
28#include <libcdvd.h>
29#include <stdarg.h>
30#include <iopcontrol.h>
31
32#include "internal.h"
33
34// rpc bind values
35#define CD_SERVER_INIT 0x80000592
36#define CD_SERVER_SEARCHFILE 0x80000597
37#define CD_SERVER_DISKREADY 0x8000059A
39#define CD_SERVER_POFF 0x80000596
40
42extern void *_gp;
43
44// prototypes
45void _CdSemaExit(void);
46
47typedef struct
48{
49 int m_init_result;
50 /* The rest of the values in this struct are only set in SDK >= 2.0.0. */
51 /* Otherwise they are zero. */
52 int m_cdvdfsv_version;
53 int m_cdvdman_version;
54 int m_cdvdfsv_isverbose;
55} CdInitPkt;
56
58typedef struct
59{
60 u8 padding[32];
61 char name[256];
62 void *dest;
64
65// version variables
66int initVersionCdvdfsv;
67int initVersionCdvdman;
68// rpc binded client data
70SifRpcClientData_t clientInit __attribute__((aligned(64)));
72SifRpcClientData_t clientDiskReady __attribute__((aligned(64)));
74SifRpcClientData_t clientSearchFile __attribute__((aligned(64)));
75
77int CdDebug = 0;
78
79// semaphore ids
83volatile int cbSema = 0;
84
85// callbacks
86volatile int CdCallbackNum;
87volatile sceCdCBFunc sceCdCallbackFunc;
88
89// threads
90int callbackThreadId = 0;
91ee_thread_t callbackThreadParam;
92
93// current command variables
94
95s32 diskReadyMode __attribute__((aligned(64)));
96u32 initMode __attribute__((aligned(64)));
97
98// init stuff
99CdInitPkt cdInitRecvBuff __attribute__((aligned(64)));
100// searchfile stuff
101SearchFilePkt searchFileSendBuff __attribute__((aligned(64)));
102
103// Prototypes for multimodule
104extern int initVersionCdvdfsv;
105extern int initVersionCdvdman;
106extern SifRpcClientData_t clientInit;
107extern SifRpcClientData_t clientDiskReady;
108extern SifRpcClientData_t clientSearchFile;
109extern int CdDebug;
110extern int callbackSemaId;
111extern volatile int cbSema;
112extern volatile int CdCallbackNum;
113extern volatile sceCdCBFunc sceCdCallbackFunc;
114extern int callbackThreadId;
115extern ee_thread_t callbackThreadParam;
116extern s32 diskReadyMode;
117extern u32 initMode;
118extern CdInitPkt cdInitRecvBuff;
119extern SearchFilePkt searchFileSendBuff;
120
121/* Other Functions */
122
123s32 sceCdInit(s32 mode)
124{
125 if (_CdSyncS(1))
126 return 0;
127 sceSifInitRpc(0);
128 memset(&clientInit, 0, sizeof(clientInit));
129
130 while (1) {
131 if (sceSifBindRpc(&clientInit, CD_SERVER_INIT, 0) < 0) {
132 if (CdDebug > 0)
133 printf("Libcdvd bind err CD_Init\n");
134 } else if (clientInit.server != 0)
135 break;
136
137 nopdelay();
138 }
139
140 initMode = mode;
141 if (sceSifCallRpc(&clientInit, 0, 0, &initMode, sizeof(initMode), &cdInitRecvBuff, sizeof(cdInitRecvBuff), 0, 0) < 0)
142 return 0;
143 initVersionCdvdfsv = cdInitRecvBuff.m_cdvdfsv_version;
144 initVersionCdvdman = cdInitRecvBuff.m_cdvdman_version;
145 if (mode == SCECdEXIT) {
146 if (CdDebug > 0)
147 printf("Libcdvd Exit\n");
148 _CdSemaExit();
149 nCmdSemaId = 0;
150 sCmdSemaId = 0;
151 callbackSemaId = 0;
152 } else {
153 _CdSemaInit();
154 }
155
156 return 1;
157}
158
160{
161 p->minute = (((((i + 150) / 75) / 60) / 10) * 16) + ((((i + 150) / 75) / 60) % 10);
162 p->second = (((((i + 150) / 75) % 60) / 10) * 16) + ((((i + 150) / 75) % 60) % 10);
163 p->sector = ((((i + 150) % 75) / 10) * 16) + (((i + 150) % 75) % 10);
164 return p;
165}
166
168{
169 return ((((p->minute / 16) * 10) + (p->minute & 0xF)) * 60 + ((p->second / 16) * 10) + (p->second & 0xF)) * 75 + (p->sector / 16) * 10 + (p->sector & 0xF) - 150;
170}
171
172s32 sceCdSearchFile(sceCdlFILE *file, const char *name)
173{
174 _CdSemaInit();
175 if (PollSema(nCmdSemaId) != nCmdSemaId)
176 return 0;
177 nCmdNum = CD_SERVER_SEARCHFILE;
178 if (sceCdSync(1)) {
179 SignalSema(nCmdSemaId);
180 return 0;
181 }
182 sceSifInitRpc(0);
183 if (HasIopRebootedSinceLastCall())
184 memset(&clientSearchFile, 0, sizeof(clientSearchFile));
185 if (!clientSearchFile.server) {
186 while (1) {
187 if (sceSifBindRpc(&clientSearchFile, CD_SERVER_SEARCHFILE, 0) < 0) {
188 if (CdDebug > 0)
189 printf("libsceCdvd bind err sceCdSearchFile\n");
190 }
191 if (clientSearchFile.server != 0)
192 break;
193
194 nopdelay();
195 }
196 }
197
198 strlcpy(searchFileSendBuff.name, name, sizeof(searchFileSendBuff.name));
199 searchFileSendBuff.dest = &searchFileSendBuff;
200
201 if (CdDebug > 0)
202 printf("ee call cmd search %s\n", searchFileSendBuff.name);
203 if (sceSifCallRpc(&clientSearchFile, 0, 0, &searchFileSendBuff, sizeof(SearchFilePkt), nCmdRecvBuff, 4, NULL, NULL) < 0) {
204 SignalSema(nCmdSemaId);
205 return 0;
206 }
207
208 memcpy(file, UNCACHED_SEG(&searchFileSendBuff), 32);
209
210 if (CdDebug > 0) {
211 printf("search name %s\n", file->name);
212 printf("search size %d\n", file->size);
213 printf("search loc lnn %d\n", file->lsn);
214 printf("search loc date %02X %02X %02X %02X %02X %02X %02X %02X\n",
215 file->date[0], file->date[1], file->date[2], file->date[3],
216 file->date[4], file->date[5], file->date[6], file->date[7]);
217 printf("search loc date %02d %02d %02d %02d %02d %02d %02d %02d\n",
218 file->date[0], file->date[1], file->date[2], file->date[3],
219 file->date[4], file->date[5], file->date[6], file->date[7]);
220 }
221
222 SignalSema(nCmdSemaId);
223 return *(s32 *)UNCACHED_SEG(nCmdRecvBuff);
224}
225
226s32 sceCdDiskReady(s32 mode)
227{
228 if (CdDebug > 0)
229 printf("DiskReady 0\n");
230
231 _CdSemaInit();
232 if (PollSema(sCmdSemaId) != sCmdSemaId)
233 return SCECdNotReady;
234 if (_CdSyncS(1)) {
235 SignalSema(sCmdSemaId);
236 return SCECdNotReady;
237 }
238
239 sceSifInitRpc(0);
240 if (HasIopRebootedSinceLastCall())
241 memset(&clientDiskReady, 0, sizeof(clientDiskReady));
242 if (!clientDiskReady.server) {
243 while (1) {
244 if (sceSifBindRpc(&clientDiskReady, CD_SERVER_DISKREADY, 0) < 0) {
245 if (CdDebug > 0)
246 printf("Libcdvd bind err CdDiskReady\n");
247 }
248 if (clientDiskReady.server != 0)
249 break;
250
251 nopdelay();
252 }
253 }
254 diskReadyMode = mode;
255
256 if (sceSifCallRpc(&clientDiskReady, 0, 0, &diskReadyMode, 4, sCmdRecvBuff, 4, NULL, NULL) < 0) {
257 SignalSema(sCmdSemaId);
258 return 6;
259 }
260 if (CdDebug > 0)
261 printf("DiskReady ended\n");
262
263 SignalSema(sCmdSemaId);
264 return *(s32 *)UNCACHED_SEG(sCmdRecvBuff);
265}
266
267void _CdSemaInit(void)
268{
269 struct t_ee_sema semaParam;
270
271 // return if both semaphores are already inited
272 if (nCmdSemaId != 0 && sCmdSemaId != 0)
273 return;
274
275 semaParam.init_count = 1;
276 semaParam.max_count = 1;
277 semaParam.option = 0;
278 nCmdSemaId = CreateSema(&semaParam);
279 if (nCmdSemaId < 0)
280 nCmdSemaId = 0;
281 sCmdSemaId = CreateSema(&semaParam);
282 if (sCmdSemaId < 0)
283 sCmdSemaId = 0;
284
285 semaParam.init_count = 0;
286 callbackSemaId = CreateSema(&semaParam);
287 if (callbackSemaId < 0)
288 callbackSemaId = 0;
289
290 cbSema = 0;
291}
292
293void _CdSemaExit(void)
294{
295 if (callbackThreadId) {
296 CdCallbackNum = -1;
297 SignalSema(callbackSemaId);
298 }
299 DeleteSema(nCmdSemaId);
300 DeleteSema(sCmdSemaId);
301 DeleteSema(callbackSemaId);
302}
303
304static void _CdCallbackLoop(void);
305s32 sceCdInitEeCB(s32 priority, void *stackAddr, s32 stackSize)
306{
307 // if callback thread has already been initialised, just change its priority
308 if (callbackThreadId != 0) {
309 ChangeThreadPriority(callbackThreadId, priority);
310 return 0;
311 }
312 // initialise callback thread
313 callbackThreadParam.stack_size = stackSize;
314 callbackThreadParam.gp_reg = &_gp;
315 callbackThreadParam.func = &_CdCallbackLoop;
316 callbackThreadParam.stack = stackAddr;
317 callbackThreadParam.initial_priority = priority;
318 callbackThreadId = CreateThread(&callbackThreadParam);
319 StartThread(callbackThreadId, NULL);
320
321 return 1;
322}
323
325{
326 sceCdCBFunc oldFunc = sceCdCallbackFunc;
327
328 if (sceCdSync(1))
329 return 0;
330
331 sceCdCallbackFunc = newFunc;
332 return oldFunc;
333}
334
335/* Util Functions */
336
337
343static void _CdCallbackLoop(void)
344{
345 while (1) {
346 WaitSema(callbackSemaId);
347
348 // if callback number if -1, stop callbck thread loop
349 if (CdCallbackNum == -1)
350 ExitThread();
351
352 if (CdDebug > 0)
353 printf("sceCdCallbackFunc = %08X CdCallbackNum = %d\n", (u32)sceCdCallbackFunc, CdCallbackNum);
354
355 // if callback function number and 'custom callback function' pointer are valid, do callback
356 if (sceCdCallbackFunc && CdCallbackNum)
357 sceCdCallbackFunc(CdCallbackNum);
358
359 cbSema = 0;
360 }
361}
362
364void _CdGenericCallbackFunction(void *funcNum)
365{
366 // set the currently executing function num
367 CdCallbackNum = *(s32 *)funcNum;
368 iSignalSema(nCmdSemaId);
369
370 // check if user callback is registered
371 if (callbackThreadId) {
372 if (sceCdCallbackFunc) {
373 iSignalSema(callbackSemaId);
374 return;
375 }
376 }
377
378 // clear the currently executing function num
379 cbSema = 0;
380 CdCallbackNum = 0;
381}
void _CdGenericCallbackFunction(void *funcNum)
Definition libcdvd.c:364
volatile int cbSema
Definition libcdvd.c:111
int CdDebug
Definition libcdvd.c:109
int nCmdSemaId
Definition ncmd.c:105
@ SCECdNotReady
void(*) sceCdCBFunc(int reason)
@ SCECdEXIT
sceCdCBFunc sceCdCallback(sceCdCBFunc newFunc)
Definition libcdvd.c:324
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition libcdvd.c:167
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
Definition libcdvd.c:159
int callbackSemaId
Definition libcdvd.c:81
void * _gp
s32 sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition libcdvd.c:172
int sceCdSync(int mode)
Definition ncmd.c:722
char name[16]