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