PS2SDK
PS2 Homebrew Libraries
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 #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
38 
39 #define CD_SERVER_POFF 0x80000596
40 
42 extern void *_gp;
43 
44 // prototypes
45 void _CdSemaExit(void);
46 
47 typedef 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 
58 typedef struct
59 {
60  u8 padding[32];
61  char name[256];
62  void *dest;
64 
65 #ifdef F__libcdvd_internals
66 // version variables
67 int initVersionCdvdfsv;
68 int initVersionCdvdman;
69 // rpc binded client data
71 SifRpcClientData_t clientInit __attribute__((aligned(64)));
73 SifRpcClientData_t clientDiskReady __attribute__((aligned(64)));
75 SifRpcClientData_t clientSearchFile __attribute__((aligned(64)));
76 
78 int CdDebug = 0;
79 
80 // semaphore ids
82 int callbackSemaId;
84 volatile int cbSema = 0;
85 
86 // callbacks
87 volatile int CdCallbackNum;
88 volatile sceCdCBFunc sceCdCallbackFunc;
89 
90 // threads
91 int callbackThreadId = 0;
92 ee_thread_t callbackThreadParam;
93 
94 // current command variables
95 
96 s32 diskReadyMode __attribute__((aligned(64)));
97 u32 initMode __attribute__((aligned(64)));
98 
99 // init stuff
100 CdInitPkt cdInitRecvBuff __attribute__((aligned(64)));
101 // searchfile stuff
102 SearchFilePkt searchFileSendBuff __attribute__((aligned(64)));
103 #endif
104 
105 // Prototypes for multimodule
106 extern int initVersionCdvdfsv;
107 extern int initVersionCdvdman;
108 extern SifRpcClientData_t clientInit;
109 extern SifRpcClientData_t clientDiskReady;
110 extern SifRpcClientData_t clientSearchFile;
111 extern int CdDebug;
112 extern int callbackSemaId;
113 extern volatile int cbSema;
114 extern volatile int CdCallbackNum;
115 extern volatile sceCdCBFunc sceCdCallbackFunc;
116 extern int callbackThreadId;
117 extern ee_thread_t callbackThreadParam;
118 extern s32 diskReadyMode;
119 extern u32 initMode;
120 extern CdInitPkt cdInitRecvBuff;
121 extern SearchFilePkt searchFileSendBuff;
122 
123 /* Other Functions */
124 
125 #ifdef F_sceCdInit
126 s32 sceCdInit(s32 mode)
127 {
128  if (_CdSyncS(1))
129  return 0;
130  sceSifInitRpc(0);
131  memset(&clientInit, 0, sizeof(clientInit));
132 
133  while (1) {
134  if (sceSifBindRpc(&clientInit, CD_SERVER_INIT, 0) < 0) {
135  if (CdDebug > 0)
136  printf("Libcdvd bind err CD_Init\n");
137  } else if (clientInit.server != 0)
138  break;
139 
140  nopdelay();
141  }
142 
143  initMode = mode;
144  if (sceSifCallRpc(&clientInit, 0, 0, &initMode, sizeof(initMode), &cdInitRecvBuff, sizeof(cdInitRecvBuff), 0, 0) < 0)
145  return 0;
146  initVersionCdvdfsv = cdInitRecvBuff.m_cdvdfsv_version;
147  initVersionCdvdman = cdInitRecvBuff.m_cdvdman_version;
148  if (mode == SCECdEXIT) {
149  if (CdDebug > 0)
150  printf("Libcdvd Exit\n");
151  _CdSemaExit();
152  nCmdSemaId = 0;
153  sCmdSemaId = 0;
154  callbackSemaId = 0;
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
181 s32 sceCdSearchFile(sceCdlFILE *file, const char *name)
182 {
183  _CdSemaInit();
184  if (PollSema(nCmdSemaId) != nCmdSemaId)
185  return 0;
186  nCmdNum = CD_SERVER_SEARCHFILE;
187  if (sceCdSync(1)) {
188  SignalSema(nCmdSemaId);
189  return 0;
190  }
191  sceSifInitRpc(0);
193  memset(&clientSearchFile, 0, sizeof(clientSearchFile));
194  if (!clientSearchFile.server) {
195  while (1) {
196  if (sceSifBindRpc(&clientSearchFile, CD_SERVER_SEARCHFILE, 0) < 0) {
197  if (CdDebug > 0)
198  printf("libsceCdvd bind err sceCdSearchFile\n");
199  }
200  if (clientSearchFile.server != 0)
201  break;
202 
203  nopdelay();
204  }
205  }
206 
207  strlcpy(searchFileSendBuff.name, name, sizeof(searchFileSendBuff.name));
208  searchFileSendBuff.dest = &searchFileSendBuff;
209 
210  if (CdDebug > 0)
211  printf("ee call cmd search %s\n", searchFileSendBuff.name);
212  if (sceSifCallRpc(&clientSearchFile, 0, 0, &searchFileSendBuff, sizeof(SearchFilePkt), nCmdRecvBuff, 4, NULL, NULL) < 0) {
213  SignalSema(nCmdSemaId);
214  return 0;
215  }
216 
217  memcpy(file, UNCACHED_SEG(&searchFileSendBuff), 32);
218 
219  if (CdDebug > 0) {
220  printf("search name %s\n", file->name);
221  printf("search size %d\n", file->size);
222  printf("search loc lnn %d\n", file->lsn);
223  printf("search loc date %02X %02X %02X %02X %02X %02X %02X %02X\n",
224  file->date[0], file->date[1], file->date[2], file->date[3],
225  file->date[4], file->date[5], file->date[6], file->date[7]);
226  printf("search loc date %02d %02d %02d %02d %02d %02d %02d %02d\n",
227  file->date[0], file->date[1], file->date[2], file->date[3],
228  file->date[4], file->date[5], file->date[6], file->date[7]);
229  }
230 
231  SignalSema(nCmdSemaId);
232  return *(s32 *)UNCACHED_SEG(nCmdRecvBuff);
233 }
234 #endif
235 
236 #ifdef F_sceCdDiskReady
237 s32 sceCdDiskReady(s32 mode)
238 {
239  if (CdDebug > 0)
240  printf("DiskReady 0\n");
241 
242  _CdSemaInit();
243  if (PollSema(sCmdSemaId) != sCmdSemaId)
244  return SCECdNotReady;
245  if (_CdSyncS(1)) {
246  SignalSema(sCmdSemaId);
247  return SCECdNotReady;
248  }
249 
250  sceSifInitRpc(0);
252  memset(&clientDiskReady, 0, sizeof(clientDiskReady));
253  if (!clientDiskReady.server) {
254  while (1) {
255  if (sceSifBindRpc(&clientDiskReady, CD_SERVER_DISKREADY, 0) < 0) {
256  if (CdDebug > 0)
257  printf("Libcdvd bind err CdDiskReady\n");
258  }
259  if (clientDiskReady.server != 0)
260  break;
261 
262  nopdelay();
263  }
264  }
265  diskReadyMode = mode;
266 
267  if (sceSifCallRpc(&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
280 void _CdSemaInit(void)
281 {
282  struct t_ee_sema semaParam;
283 
284  // return if both semaphores are already inited
285  if (nCmdSemaId != 0 && sCmdSemaId != 0)
286  return;
287 
288  semaParam.init_count = 1;
289  semaParam.max_count = 1;
290  semaParam.option = 0;
291  nCmdSemaId = CreateSema(&semaParam);
292  if (nCmdSemaId < 0)
293  nCmdSemaId = 0;
294  sCmdSemaId = CreateSema(&semaParam);
295  if (sCmdSemaId < 0)
296  sCmdSemaId = 0;
297 
298  semaParam.init_count = 0;
299  callbackSemaId = CreateSema(&semaParam);
300  if (callbackSemaId < 0)
301  callbackSemaId = 0;
302 
303  cbSema = 0;
304 }
305 #endif
306 
307 #ifdef F__CdSemaExit
308 void _CdSemaExit(void)
309 {
310  if (callbackThreadId) {
311  CdCallbackNum = -1;
312  SignalSema(callbackSemaId);
313  }
314  DeleteSema(nCmdSemaId);
315  DeleteSema(sCmdSemaId);
316  DeleteSema(callbackSemaId);
317 }
318 #endif
319 
320 #ifdef F_sceCdInitEeCB
321 static void _CdCallbackLoop(void);
322 s32 sceCdInitEeCB(s32 priority, void *stackAddr, s32 stackSize)
323 {
324  // if callback thread has already been initialised, just change its priority
325  if (callbackThreadId != 0) {
326  ChangeThreadPriority(callbackThreadId, priority);
327  return 0;
328  }
329  // initialise callback thread
330  callbackThreadParam.stack_size = stackSize;
331  callbackThreadParam.gp_reg = &_gp;
332  callbackThreadParam.func = &_CdCallbackLoop;
333  callbackThreadParam.stack = stackAddr;
334  callbackThreadParam.initial_priority = priority;
335  callbackThreadId = CreateThread(&callbackThreadParam);
336  StartThread(callbackThreadId, NULL);
337 
338  return 1;
339 }
340 #endif
341 
342 #ifdef F_sceCdCallback
344 {
345  sceCdCBFunc oldFunc = sceCdCallbackFunc;
346 
347  if (sceCdSync(1))
348  return 0;
349 
350  sceCdCallbackFunc = newFunc;
351  return oldFunc;
352 }
353 #endif
354 
355 /* Util Functions */
356 
357 
363 #ifdef F_sceCdInitEeCB
364 static void _CdCallbackLoop(void)
365 {
366  while (1) {
367  WaitSema(callbackSemaId);
368 
369  // if callback number if -1, stop callbck thread loop
370  if (CdCallbackNum == -1)
371  ExitThread();
372 
373  if (CdDebug > 0)
374  printf("sceCdCallbackFunc = %08X CdCallbackNum = %d\n", (u32)sceCdCallbackFunc, CdCallbackNum);
375 
376  // if callback function number and 'custom callback function' pointer are valid, do callback
377  if (sceCdCallbackFunc && CdCallbackNum)
378  sceCdCallbackFunc(CdCallbackNum);
379 
380  cbSema = 0;
381  }
382 }
383 #endif
384 
386 #ifdef F__CdGenericCallbackFunction
387 void _CdGenericCallbackFunction(void *funcNum)
388 {
389  // set the currently executing function num
390  CdCallbackNum = *(s32 *)funcNum;
391  iSignalSema(nCmdSemaId);
392 
393  // check if user callback is registered
394  if (callbackThreadId) {
395  if (sceCdCallbackFunc) {
396  iSignalSema(callbackSemaId);
397  return;
398  }
399  }
400 
401  // clear the currently executing function num
402  cbSema = 0;
403  CdCallbackNum = 0;
404 }
405 #endif
kernel.h
CdInitPkt
Definition: libcdvd.c:47
sceCdlFILE::name
char name[16]
Definition: libcdvd-common.h:215
sceCdInitEeCB
int sceCdInitEeCB(int priority, void *stackAddr, int stackSize)
sceCdSync
int sceCdSync(int mode)
Definition: cdi.c:109
sceCdlFILE::size
u32 size
Definition: libcdvd-common.h:213
libcdvd.h
iopcontrol.h
SCECdEXIT
@ SCECdEXIT
Definition: libcdvd-common.h:286
t_ee_sema
Definition: kernel.h:193
sceCdlFILE::lsn
u32 lsn
Definition: libcdvd-common.h:211
sceCdIntToPos
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
Definition: cdvdman.c:2402
sceCdlFILE
Definition: libcdvd-common.h:208
SearchFilePkt
Definition: libcdvd.c:58
_gp
void * _gp
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
SCECdNotReady
@ SCECdNotReady
Definition: libcdvd-common.h:156
sceCdCallback
sceCdCBFunc sceCdCallback(sceCdCBFunc function)
Definition: cdi.c:16
tamtypes.h
HasIopRebootedSinceLastCall
static int HasIopRebootedSinceLastCall(void)
Definition: iopcontrol.h:47
stdio.h
sceCdCBFunc
void(* sceCdCBFunc)(int reason)
Definition: libcdvd-common.h:278
sceCdInit
int sceCdInit(int mode)
Definition: cdi.c:64
sceCdlFILE::date
u8 date[8]
Definition: libcdvd-common.h:217
sceCdPosToInt
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition: cdvdman.c:2411
sceCdSearchFile
int sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition: cdi.c:114
t_SifRpcClientData
Definition: sifrpc-common.h:134
__attribute__
Definition: gif_registers.h:38
t_ee_thread
Definition: kernel.h:203
sceCdDiskReady
int sceCdDiskReady(int mode)
Definition: cdi.c:30
sceCdlLOCCD
Definition: libcdvd-common.h:221