PS2SDK
PS2 Homebrew Libraries
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
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
31#include "internal.h"
32
33// rpc bind values
34#define CD_SERVER_INIT 0x80000592
35#define CD_SERVER_SEARCHFILE 0x80000597
36#define CD_SERVER_DISKREADY 0x8000059A
38#define CD_SERVER_POFF 0x80000596
39
41extern void *_gp;
42
43// prototypes
44void _CdSemaExit(void);
45
47typedef struct
48{
49 u8 padding[32];
50 char name[256];
51 void *dest;
53
54#ifdef F__libcdvd_internals
55// bind variables
56int bindInit = -1;
57int bindDiskReady = -1;
58int bindSearchFile = -1;
59// rpc binded client data
63SifRpcClientData_t clientDiskReady __attribute__((aligned(64)));
65SifRpcClientData_t clientSearchFile __attribute__((aligned(64)));
66
68int CdDebug = 0;
69
70// semaphore ids
72int callbackSemaId = -1;
74volatile int cbSema = 0;
75
76// callbacks
77volatile int CdCallbackNum;
78volatile sceCdCBFunc sceCdCallbackFunc;
79
80// threads
81int CdThreadId = 0;
82ee_thread_status_t CdThreadParam;
83int callbackThreadId = 0;
84ee_thread_t callbackThreadParam;
85
86// current command variables
87
88s32 diskReadyMode __attribute__((aligned(64)));
89s32 trayReqData __attribute__((aligned(64)));
90u32 initMode __attribute__((aligned(64)));
91
92// searchfile stuff
93SearchFilePkt searchFileSendBuff __attribute__((aligned(64)));
94u32 searchFileRecvBuff __attribute__((aligned(64)));
95#endif
96
97// Prototypes for multimodule
98extern int bindInit;
99extern int bindDiskReady;
100extern int bindSearchFile;
101extern SifRpcClientData_t clientInit;
102extern SifRpcClientData_t clientDiskReady;
103extern SifRpcClientData_t clientSearchFile;
104extern int CdDebug;
105extern int callbackSemaId;
106extern volatile int cbSema;
107extern volatile int CdCallbackNum;
108extern volatile sceCdCBFunc sceCdCallbackFunc;
109extern int CdThreadId;
110extern ee_thread_status_t CdThreadParam;
111extern int callbackThreadId;
112extern ee_thread_t callbackThreadParam;
113extern s32 diskReadyMode;
114extern s32 trayReqData;
115extern u32 initMode;
116extern SearchFilePkt searchFileSendBuff;
117extern u32 searchFileRecvBuff;
118
119/* Other Functions */
120
121#ifdef F_sceCdInit
122s32 sceCdInit(s32 mode)
123{
124 if (_CdSyncS(1))
125 return 0;
126 SifInitRpc(0);
127 CdThreadId = GetThreadId();
128 bindSearchFile = -1;
129 bindNCmd = -1;
130 bindSCmd = -1;
131 bindDiskReady = -1;
132 bindInit = -1;
133
134 while (1) {
135 if (SifBindRpc(&clientInit, CD_SERVER_INIT, 0) < 0) {
136 if (CdDebug > 0)
137 printf("Libcdvd bind err CD_Init\n");
138 } else if (clientInit.server != 0)
139 break;
140
141 nopdelay();
142 }
143
144 bindInit = 0;
145 initMode = mode;
146 if (SifCallRpc(&clientInit, 0, 0, &initMode, 4, 0, 0, 0, 0) < 0)
147 return 0;
148 if (mode == SCECdEXIT) {
149 if (CdDebug > 0)
150 printf("Libcdvd Exit\n");
151 _CdSemaExit();
152 nCmdSemaId = -1;
153 sCmdSemaId = -1;
154 callbackSemaId = -1;
155 } else {
156 _CdSemaInit();
157 }
158
159 return 1;
160}
161#endif
162
163#ifdef F_sceCdIntToPos
165{
166 p->minute = (((((i + 150) / 75) / 60) / 10) * 16) + ((((i + 150) / 75) / 60) % 10);
167 p->second = (((((i + 150) / 75) % 60) / 10) * 16) + ((((i + 150) / 75) % 60) % 10);
168 p->sector = ((((i + 150) % 75) / 10) * 16) + (((i + 150) % 75) % 10);
169 return p;
170}
171#endif
172
173#ifdef F_sceCdPosToInt
175{
176 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;
177}
178#endif
179
180#ifdef F_sceCdSearchFile
181s32 sceCdSearchFile(sceCdlFILE *file, const char *name)
182{
183 _CdSemaInit();
184 if (PollSema(nCmdSemaId) != nCmdSemaId)
185 return 0;
186 nCmdNum = CD_SERVER_SEARCHFILE;
187 ReferThreadStatus(CdThreadId, &CdThreadParam);
188 if (sceCdSync(1)) {
189 SignalSema(nCmdSemaId);
190 return 0;
191 }
192 SifInitRpc(0);
193 if (bindSearchFile < 0) {
194 while (1) {
195 if (SifBindRpc(&clientSearchFile, CD_SERVER_SEARCHFILE, 0) < 0) {
196 if (CdDebug > 0)
197 printf("libsceCdvd bind err sceCdSearchFile\n");
198 }
199 if (clientSearchFile.server != 0)
200 break;
201
202 nopdelay();
203 }
204 bindSearchFile = 0;
205 }
206
207 strncpy(searchFileSendBuff.name, name, 255);
208 searchFileSendBuff.name[255] = '\0';
209 searchFileSendBuff.dest = &searchFileSendBuff;
210
211 if (CdDebug > 0)
212 printf("ee call cmd search %s\n", searchFileSendBuff.name);
213 if (SifCallRpc(&clientSearchFile, 0, 0, &searchFileSendBuff, sizeof(SearchFilePkt), nCmdRecvBuff, 4, NULL, NULL) < 0) {
214 SignalSema(nCmdSemaId);
215 return 0;
216 }
217
218 memcpy(file, UNCACHED_SEG(&searchFileSendBuff), 32);
219
220 if (CdDebug > 0) {
221 printf("search name %s\n", file->name);
222 printf("search size %d\n", file->size);
223 printf("search loc lnn %d\n", file->lsn);
224 printf("search loc date %02X %02X %02X %02X %02X %02X %02X %02X\n",
225 file->date[0], file->date[1], file->date[2], file->date[3],
226 file->date[4], file->date[5], file->date[6], file->date[7]);
227 printf("search loc date %02d %02d %02d %02d %02d %02d %02d %02d\n",
228 file->date[0], file->date[1], file->date[2], file->date[3],
229 file->date[4], file->date[5], file->date[6], file->date[7]);
230 }
231
232 SignalSema(nCmdSemaId);
233 return *(s32 *)UNCACHED_SEG(nCmdRecvBuff);
234}
235#endif
236
237#ifdef F_sceCdDiskReady
238s32 sceCdDiskReady(s32 mode)
239{
240 if (CdDebug > 0)
241 printf("DiskReady 0\n");
242
243 _CdSemaInit();
244 if (PollSema(sCmdSemaId) != sCmdSemaId)
245 return SCECdNotReady;
246 if (_CdSyncS(1)) {
247 SignalSema(sCmdSemaId);
248 return SCECdNotReady;
249 }
250
251 SifInitRpc(0);
252 if (bindDiskReady < 0) {
253 while (1) {
254 if (SifBindRpc(&clientDiskReady, CD_SERVER_DISKREADY, 0) < 0) {
255 if (CdDebug > 0)
256 printf("Libcdvd bind err CdDiskReady\n");
257 }
258 if (clientDiskReady.server != 0)
259 break;
260
261 nopdelay();
262 }
263 }
264 bindDiskReady = 0;
265 diskReadyMode = mode;
266
267 if (SifCallRpc(&clientDiskReady, 0, 0, &diskReadyMode, 4, sCmdRecvBuff, 4, NULL, NULL) < 0) {
268 SignalSema(sCmdSemaId);
269 return 6;
270 }
271 if (CdDebug > 0)
272 printf("DiskReady ended\n");
273
274 SignalSema(sCmdSemaId);
275 return *(s32 *)UNCACHED_SEG(sCmdRecvBuff);
276}
277#endif
278
279#ifdef F__CdSemaInit
280void _CdSemaInit(void)
281{
282 struct t_ee_sema semaParam;
283
284 // return if both semaphores are already inited
285 if (nCmdSemaId != -1 && sCmdSemaId != -1)
286 return;
287
288 semaParam.init_count = 1;
289 semaParam.max_count = 1;
290 semaParam.option = 0;
291 nCmdSemaId = CreateSema(&semaParam);
292 sCmdSemaId = CreateSema(&semaParam);
293
294 semaParam.init_count = 0;
295 callbackSemaId = CreateSema(&semaParam);
296
297 cbSema = 0;
298}
299#endif
300
301#ifdef F__CdSemaExit
302void _CdSemaExit(void)
303{
304 if (callbackThreadId) {
305 CdCallbackNum = -1;
306 SignalSema(callbackSemaId);
307 }
308 DeleteSema(nCmdSemaId);
309 DeleteSema(sCmdSemaId);
310 DeleteSema(callbackSemaId);
311}
312#endif
313
314#ifdef F_sceCdInitEeCB
315static void _CdCallbackLoop(void);
316s32 sceCdInitEeCB(s32 priority, void *stackAddr, s32 stackSize)
317{
318 // if callback thread has already been initialised, just change its priority
319 if (callbackThreadId != 0) {
320 ChangeThreadPriority(callbackThreadId, priority);
321 return 0;
322 }
323 // initialise callback thread
324 CdThreadId = GetThreadId();
325 ReferThreadStatus(CdThreadId, &CdThreadParam);
326 callbackThreadParam.stack_size = stackSize;
327 callbackThreadParam.gp_reg = &_gp;
328 callbackThreadParam.func = &_CdCallbackLoop;
329 callbackThreadParam.stack = stackAddr;
330 callbackThreadParam.initial_priority = priority;
331 callbackThreadId = CreateThread(&callbackThreadParam);
332 StartThread(callbackThreadId, NULL);
333
334 return 1;
335}
336#endif
337
338#ifdef F_sceCdCallback
340{
341 sceCdCBFunc oldFunc = sceCdCallbackFunc;
342
343 if (sceCdSync(1))
344 return 0;
345
346 sceCdCallbackFunc = newFunc;
347 return oldFunc;
348}
349#endif
350
351/* Util Functions */
352
353
359#ifdef F_sceCdInitEeCB
360static void _CdCallbackLoop(void)
361{
362 while (1) {
363 WaitSema(callbackSemaId);
364
365 // if callback number if -1, stop callbck thread loop
366 if (CdCallbackNum == -1)
367 ExitThread();
368
369 if (CdDebug > 0)
370 printf("sceCdCallbackFunc = %08X CdCallbackNum = %d\n", (u32)sceCdCallbackFunc, CdCallbackNum);
371
372 // if callback function number and 'custom callback function' pointer are valid, do callback
373 if (sceCdCallbackFunc && CdCallbackNum)
374 sceCdCallbackFunc(CdCallbackNum);
375
376 cbSema = 0;
377 }
378}
379#endif
380
382#ifdef F__CdGenericCallbackFunction
383void _CdGenericCallbackFunction(void *funcNum)
384{
385 // set the currently executing function num
386 CdCallbackNum = *(s32 *)funcNum;
387 iSignalSema(nCmdSemaId);
388
389 // check if user callback is registered
390 if (callbackThreadId) {
391 if (sceCdCallbackFunc) {
392 iSignalSema(callbackSemaId);
393 return;
394 }
395 }
396
397 // clear the currently executing function num
398 cbSema = 0;
399 CdCallbackNum = 0;
400}
401#endif
char name[16]
int sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition cdi.c:114
@ SCECdNotReady
int sceCdInitEeCB(int priority, void *stackAddr, int stackSize)
int sceCdInit(int mode)
Definition cdi.c:64
sceCdCBFunc sceCdCallback(sceCdCBFunc function)
Definition cdi.c:16
int sceCdDiskReady(int mode)
Definition cdi.c:30
u32 sceCdPosToInt(sceCdlLOCCD *p)
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
int sceCdSync(int mode)
Definition cdi.c:109
void(* sceCdCBFunc)(int reason)
@ SCECdEXIT
void * _gp