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 CdThreadId = 0;
92 ee_thread_status_t CdThreadParam;
93 int callbackThreadId = 0;
94 ee_thread_t callbackThreadParam;
95 
96 // current command variables
97 
98 s32 diskReadyMode __attribute__((aligned(64)));
99 s32 trayReqData __attribute__((aligned(64)));
100 u32 initMode __attribute__((aligned(64)));
101 
102 // init stuff
103 CdInitPkt cdInitRecvBuff __attribute__((aligned(64)));
104 // searchfile stuff
105 SearchFilePkt searchFileSendBuff __attribute__((aligned(64)));
106 u32 searchFileRecvBuff __attribute__((aligned(64)));
107 #endif
108 
109 // Prototypes for multimodule
110 extern int initVersionCdvdfsv;
111 extern int initVersionCdvdman;
112 extern SifRpcClientData_t clientInit;
113 extern SifRpcClientData_t clientDiskReady;
114 extern SifRpcClientData_t clientSearchFile;
115 extern int CdDebug;
116 extern int callbackSemaId;
117 extern volatile int cbSema;
118 extern volatile int CdCallbackNum;
119 extern volatile sceCdCBFunc sceCdCallbackFunc;
120 extern int CdThreadId;
121 extern ee_thread_status_t CdThreadParam;
122 extern int callbackThreadId;
123 extern ee_thread_t callbackThreadParam;
124 extern s32 diskReadyMode;
125 extern s32 trayReqData;
126 extern u32 initMode;
127 extern CdInitPkt cdInitRecvBuff;
128 extern SearchFilePkt searchFileSendBuff;
129 extern u32 searchFileRecvBuff;
130 
131 /* Other Functions */
132 
133 #ifdef F_sceCdInit
134 s32 sceCdInit(s32 mode)
135 {
136  if (_CdSyncS(1))
137  return 0;
138  sceSifInitRpc(0);
139  CdThreadId = GetThreadId();
140  memset(&clientInit, 0, sizeof(clientInit));
141 
142  while (1) {
143  if (sceSifBindRpc(&clientInit, CD_SERVER_INIT, 0) < 0) {
144  if (CdDebug > 0)
145  printf("Libcdvd bind err CD_Init\n");
146  } else if (clientInit.server != 0)
147  break;
148 
149  nopdelay();
150  }
151 
152  initMode = mode;
153  if (sceSifCallRpc(&clientInit, 0, 0, &initMode, sizeof(initMode), &cdInitRecvBuff, sizeof(cdInitRecvBuff), 0, 0) < 0)
154  return 0;
155  initVersionCdvdfsv = cdInitRecvBuff.m_cdvdfsv_version;
156  initVersionCdvdman = cdInitRecvBuff.m_cdvdman_version;
157  if (mode == SCECdEXIT) {
158  if (CdDebug > 0)
159  printf("Libcdvd Exit\n");
160  _CdSemaExit();
161  nCmdSemaId = 0;
162  sCmdSemaId = 0;
163  callbackSemaId = 0;
164  } else {
165  _CdSemaInit();
166  }
167 
168  return 1;
169 }
170 #endif
171 
172 #ifdef F_sceCdIntToPos
174 {
175  p->minute = (((((i + 150) / 75) / 60) / 10) * 16) + ((((i + 150) / 75) / 60) % 10);
176  p->second = (((((i + 150) / 75) % 60) / 10) * 16) + ((((i + 150) / 75) % 60) % 10);
177  p->sector = ((((i + 150) % 75) / 10) * 16) + (((i + 150) % 75) % 10);
178  return p;
179 }
180 #endif
181 
182 #ifdef F_sceCdPosToInt
184 {
185  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;
186 }
187 #endif
188 
189 #ifdef F_sceCdSearchFile
190 s32 sceCdSearchFile(sceCdlFILE *file, const char *name)
191 {
192  _CdSemaInit();
193  if (PollSema(nCmdSemaId) != nCmdSemaId)
194  return 0;
195  nCmdNum = CD_SERVER_SEARCHFILE;
196  ReferThreadStatus(CdThreadId, &CdThreadParam);
197  if (sceCdSync(1)) {
198  SignalSema(nCmdSemaId);
199  return 0;
200  }
201  sceSifInitRpc(0);
203  memset(&clientSearchFile, 0, sizeof(clientSearchFile));
204  if (!clientSearchFile.server) {
205  while (1) {
206  if (sceSifBindRpc(&clientSearchFile, CD_SERVER_SEARCHFILE, 0) < 0) {
207  if (CdDebug > 0)
208  printf("libsceCdvd bind err sceCdSearchFile\n");
209  }
210  if (clientSearchFile.server != 0)
211  break;
212 
213  nopdelay();
214  }
215  }
216 
217  strncpy(searchFileSendBuff.name, name, 255);
218  searchFileSendBuff.name[255] = '\0';
219  searchFileSendBuff.dest = &searchFileSendBuff;
220 
221  if (CdDebug > 0)
222  printf("ee call cmd search %s\n", searchFileSendBuff.name);
223  if (sceSifCallRpc(&clientSearchFile, 0, 0, &searchFileSendBuff, sizeof(SearchFilePkt), nCmdRecvBuff, 4, NULL, NULL) < 0) {
224  SignalSema(nCmdSemaId);
225  return 0;
226  }
227 
228  memcpy(file, UNCACHED_SEG(&searchFileSendBuff), 32);
229 
230  if (CdDebug > 0) {
231  printf("search name %s\n", file->name);
232  printf("search size %d\n", file->size);
233  printf("search loc lnn %d\n", file->lsn);
234  printf("search loc date %02X %02X %02X %02X %02X %02X %02X %02X\n",
235  file->date[0], file->date[1], file->date[2], file->date[3],
236  file->date[4], file->date[5], file->date[6], file->date[7]);
237  printf("search loc date %02d %02d %02d %02d %02d %02d %02d %02d\n",
238  file->date[0], file->date[1], file->date[2], file->date[3],
239  file->date[4], file->date[5], file->date[6], file->date[7]);
240  }
241 
242  SignalSema(nCmdSemaId);
243  return *(s32 *)UNCACHED_SEG(nCmdRecvBuff);
244 }
245 #endif
246 
247 #ifdef F_sceCdDiskReady
248 s32 sceCdDiskReady(s32 mode)
249 {
250  if (CdDebug > 0)
251  printf("DiskReady 0\n");
252 
253  _CdSemaInit();
254  if (PollSema(sCmdSemaId) != sCmdSemaId)
255  return SCECdNotReady;
256  if (_CdSyncS(1)) {
257  SignalSema(sCmdSemaId);
258  return SCECdNotReady;
259  }
260 
261  sceSifInitRpc(0);
263  memset(&clientDiskReady, 0, sizeof(clientDiskReady));
264  if (!clientDiskReady.server) {
265  while (1) {
266  if (sceSifBindRpc(&clientDiskReady, CD_SERVER_DISKREADY, 0) < 0) {
267  if (CdDebug > 0)
268  printf("Libcdvd bind err CdDiskReady\n");
269  }
270  if (clientDiskReady.server != 0)
271  break;
272 
273  nopdelay();
274  }
275  }
276  diskReadyMode = mode;
277 
278  if (sceSifCallRpc(&clientDiskReady, 0, 0, &diskReadyMode, 4, sCmdRecvBuff, 4, NULL, NULL) < 0) {
279  SignalSema(sCmdSemaId);
280  return 6;
281  }
282  if (CdDebug > 0)
283  printf("DiskReady ended\n");
284 
285  SignalSema(sCmdSemaId);
286  return *(s32 *)UNCACHED_SEG(sCmdRecvBuff);
287 }
288 #endif
289 
290 #ifdef F__CdSemaInit
291 void _CdSemaInit(void)
292 {
293  struct t_ee_sema semaParam;
294 
295  // return if both semaphores are already inited
296  if (nCmdSemaId != 0 && sCmdSemaId != 0)
297  return;
298 
299  semaParam.init_count = 1;
300  semaParam.max_count = 1;
301  semaParam.option = 0;
302  nCmdSemaId = CreateSema(&semaParam);
303  if (nCmdSemaId < 0)
304  nCmdSemaId = 0;
305  sCmdSemaId = CreateSema(&semaParam);
306  if (sCmdSemaId < 0)
307  sCmdSemaId = 0;
308 
309  semaParam.init_count = 0;
310  callbackSemaId = CreateSema(&semaParam);
311  if (callbackSemaId < 0)
312  callbackSemaId = 0;
313 
314  cbSema = 0;
315 }
316 #endif
317 
318 #ifdef F__CdSemaExit
319 void _CdSemaExit(void)
320 {
321  if (callbackThreadId) {
322  CdCallbackNum = -1;
323  SignalSema(callbackSemaId);
324  }
325  DeleteSema(nCmdSemaId);
326  DeleteSema(sCmdSemaId);
327  DeleteSema(callbackSemaId);
328 }
329 #endif
330 
331 #ifdef F_sceCdInitEeCB
332 static void _CdCallbackLoop(void);
333 s32 sceCdInitEeCB(s32 priority, void *stackAddr, s32 stackSize)
334 {
335  // if callback thread has already been initialised, just change its priority
336  if (callbackThreadId != 0) {
337  ChangeThreadPriority(callbackThreadId, priority);
338  return 0;
339  }
340  // initialise callback thread
341  CdThreadId = GetThreadId();
342  ReferThreadStatus(CdThreadId, &CdThreadParam);
343  callbackThreadParam.stack_size = stackSize;
344  callbackThreadParam.gp_reg = &_gp;
345  callbackThreadParam.func = &_CdCallbackLoop;
346  callbackThreadParam.stack = stackAddr;
347  callbackThreadParam.initial_priority = priority;
348  callbackThreadId = CreateThread(&callbackThreadParam);
349  StartThread(callbackThreadId, NULL);
350 
351  return 1;
352 }
353 #endif
354 
355 #ifdef F_sceCdCallback
357 {
358  sceCdCBFunc oldFunc = sceCdCallbackFunc;
359 
360  if (sceCdSync(1))
361  return 0;
362 
363  sceCdCallbackFunc = newFunc;
364  return oldFunc;
365 }
366 #endif
367 
368 /* Util Functions */
369 
370 
376 #ifdef F_sceCdInitEeCB
377 static void _CdCallbackLoop(void)
378 {
379  while (1) {
380  WaitSema(callbackSemaId);
381 
382  // if callback number if -1, stop callbck thread loop
383  if (CdCallbackNum == -1)
384  ExitThread();
385 
386  if (CdDebug > 0)
387  printf("sceCdCallbackFunc = %08X CdCallbackNum = %d\n", (u32)sceCdCallbackFunc, CdCallbackNum);
388 
389  // if callback function number and 'custom callback function' pointer are valid, do callback
390  if (sceCdCallbackFunc && CdCallbackNum)
391  sceCdCallbackFunc(CdCallbackNum);
392 
393  cbSema = 0;
394  }
395 }
396 #endif
397 
399 #ifdef F__CdGenericCallbackFunction
400 void _CdGenericCallbackFunction(void *funcNum)
401 {
402  // set the currently executing function num
403  CdCallbackNum = *(s32 *)funcNum;
404  iSignalSema(nCmdSemaId);
405 
406  // check if user callback is registered
407  if (callbackThreadId) {
408  if (sceCdCallbackFunc) {
409  iSignalSema(callbackSemaId);
410  return;
411  }
412  }
413 
414  // clear the currently executing function num
415  cbSema = 0;
416  CdCallbackNum = 0;
417 }
418 #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
t_ee_thread_status
Definition: kernel.h:231
__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