PS2SDK
PS2 Homebrew Libraries
ncmd.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> Licenced under Academic Free License version 2.0
9 # Review ps2sdk README & LICENSE files for further details.
10 */
11 
22 #include <stdio.h>
23 #include <kernel.h>
24 #include <sifrpc.h>
25 #include <libcdvd.h>
26 #include <libcdvd-rpc.h>
27 #include <string.h>
28 #include <iopcontrol.h>
29 
30 #include "internal.h"
31 
33 #define CD_SERVER_NCMD 0x80000595
34 
36 typedef enum {
37  CDVD_ST_CMD_START = 1,
38  CDVD_ST_CMD_READ,
39  CDVD_ST_CMD_STOP,
40  CDVD_ST_CMD_SEEK,
41  CDVD_ST_CMD_INIT,
42  CDVD_ST_CMD_STAT,
43  CDVD_ST_CMD_PAUSE,
44  CDVD_ST_CMD_RESUME,
45  CDVD_ST_CMD_SEEKF
46 } CdvdStCmd_t;
47 
48 int sceCdStream(u32 lbn, u32 nsectors, void *buf, CdvdStCmd_t cmd, sceCdRMode *rm);
49 int sceCdCddaStream(u32 lbn, u32 nsectors, void *buf, CdvdStCmd_t cmd, sceCdRMode *rm);
50 
52  CD_NCMD_READ = 0x01,
53  CD_NCMD_CDDAREAD,
54  CD_NCMD_DVDREAD,
55  CD_NCMD_GETTOC,
56  CD_NCMD_SEEK,
57  CD_NCMD_STANDBY,
58  CD_NCMD_STOP,
59  CD_NCMD_PAUSE,
60  CD_NCMD_STREAM,
61  CD_NCMD_CDDASTREAM,
62  CD_NCMD_READ_KEY,
63  CD_NCMD_NCMD,
64  CD_NCMD_READIOPMEM,
65  CD_NCMD_DISKREADY,
68 };
69 
70 int _CdCheckNCmd(int cmd);
71 
72 typedef union
73 {
74  struct cdvdNcmdParam ncmd;
75  struct cdvdReadKeyParam readKey;
76  u8 data[48];
78 
79 #ifdef F__ncmd_internals
80 
81 SifRpcClientData_t clientNCmd __attribute__((aligned(64)));
82 
84 int nCmdSemaId;
85 
86 int nCmdNum = 0;
87 
88 u32 readStreamData[5] __attribute__((aligned(64)));
89 u32 readData[6] __attribute__((aligned(64)));
90 sceCdRChain readChainData[66] __attribute__((aligned(64)));
92 u32 getTocSendBuff[3] __attribute__((aligned(64)));
93 u32 _rd_intr_data[64] __attribute__((aligned(64)));
94 u32 curReadPos __attribute__((aligned(64)));
96 u8 tocBuff[2064] __attribute__((aligned(64)));
97 u8 nCmdRecvBuff[48] __attribute__((aligned(64)));
98 nCmdSendParams_t nCmdSendBuff __attribute__((aligned(64)));
99 int streamStatus = 0;
100 sceCdRMode dummyMode;
101 u32 seekSector __attribute__((aligned(64)));
102 u32 cdda_st_buf[64 / sizeof(u32)] ALIGNED(64);
103 #endif
104 
105 extern int initVersionCdvdfsv;
106 extern int bindNcmd;
107 extern SifRpcClientData_t clientNCmd;
108 extern int nCmdSemaId;
109 extern int nCmdNum;
110 extern u32 readStreamData[5];
111 extern u32 readData[6];
112 extern sceCdRChain readChainData[66];
113 extern u32 getTocSendBuff[3];
114 extern u32 _rd_intr_data[64];
115 extern u32 curReadPos;
116 extern u8 tocBuff[2064];
117 extern u8 nCmdRecvBuff[48];
118 extern nCmdSendParams_t nCmdSendBuff;
119 extern int streamStatus;
120 extern sceCdRMode dummyMode;
121 extern u32 seekSector;
122 extern u32 cdda_st_buf[64 / sizeof(u32)];
123 
124 int sceCdNCmdDiskReady(void);
125 
126 /* N-Command Functions */
127 
129 {
130  u32 size1;
131  u32 size2;
132  void *dest1;
133  void *dest2;
134  u8 src1[64];
135  u8 src2[64];
136 };
138 {
139  u32 size1;
140  u32 size2;
141  void *dest1;
142  void *dest2;
143  u8 src1[16];
144  u8 src2[16];
145 };
146 
147 extern void _CdAlignReadBuffer(void *data);
151 #ifdef F__CdAlignReadBuffer
152 void _CdAlignReadBuffer(void *data)
153 {
154  if (initVersionCdvdfsv > 0x104)
155  {
156  struct _cdvd_read_data_1400 *uncached = UNCACHED_SEG(data);
157 
158  if (uncached->size1 && uncached->dest1) {
159  memcpy(uncached->dest1, &uncached->src1, uncached->size1);
160  }
161 
162  if (uncached->size2 && uncached->dest2) {
163  memcpy(uncached->dest2, &uncached->src2, uncached->size2);
164  }
165  }
166  else
167  {
168  struct _cdvd_read_data_1300 *uncached = UNCACHED_SEG(data);
169 
170  if (uncached->size1 && uncached->dest1) {
171  memcpy(uncached->dest1, &uncached->src1, uncached->size1);
172  }
173 
174  if (uncached->size2 && uncached->dest2) {
175  memcpy(uncached->dest2, &uncached->src2, uncached->size2);
176  }
177  }
178 
179  _CdGenericCallbackFunction((void *)&CdCallbackNum);
180 }
181 
182 #endif
183 
184 #ifdef F_sceCdRead
185 int sceCdRead(u32 lbn, u32 sectors, void *buf, sceCdRMode *mode)
186 {
187  int bufSize;
188 
190  return 0;
191  if (_CdCheckNCmd(CD_NCMD_READ) == 0)
192  return 0;
193 
194  readData[0] = lbn;
195  readData[1] = sectors;
196  readData[2] = (u32)buf;
197  readData[3] = (mode->trycount) | (mode->spindlctrl << 8) | (mode->datapattern << 16);
198  readData[4] = (u32)_rd_intr_data;
199  readData[5] = (u32)&curReadPos;
200 
201  // work out buffer size
202  if (mode->datapattern == SCECdSecS2328)
203  bufSize = sectors * 2328;
204  else if (mode->datapattern == SCECdSecS2340)
205  bufSize = sectors * 2340;
206  else
207  bufSize = sectors * 2048;
208 
209  curReadPos = 0;
210  sceSifWriteBackDCache(buf, bufSize);
211  sceSifWriteBackDCache(&curReadPos, sizeof(curReadPos));
212 
213  if (CdDebug > 0)
214  printf("call sceCdread cmd\n");
215 
216  CdCallbackNum = CD_NCMD_READ;
217  cbSema = 1;
218 
219  if (sceSifCallRpc(&clientNCmd, CD_NCMD_READ, SIF_RPC_M_NOWAIT, readData, 24, NULL, 0, &_CdAlignReadBuffer, _rd_intr_data) < 0) {
220  CdCallbackNum = 0;
221  cbSema = 0;
222  SignalSema(nCmdSemaId);
223  return 0;
224  }
225 
226  if (CdDebug > 0)
227  printf("sceCdread end\n");
228 
229  // Old versions have this extra SignalSema call here.
230  // SignalSema(nCmdSemaId);
231  return 1;
232 }
233 #endif
234 
235 #ifdef F_sceCdReadDVDV
236 int sceCdReadDVDV(u32 lbn, u32 nsectors, void *buf, sceCdRMode *rm)
237 {
239  return 0;
240  if (_CdCheckNCmd(CD_NCMD_DVDREAD) == 0)
241  return 0;
242 
243  readData[0] = lbn;
244  readData[1] = nsectors;
245  readData[2] = (u32)buf;
246  readData[3] = (rm->trycount) | (rm->spindlctrl << 8) | (rm->datapattern << 16);
247  readData[4] = (u32)_rd_intr_data;
248 
249  sceSifWriteBackDCache(buf, nsectors * 2064);
250 
251  CdCallbackNum = CD_NCMD_DVDREAD;
252  cbSema = 1;
253 
254  if (sceSifCallRpc(&clientNCmd, CD_NCMD_DVDREAD, SIF_RPC_M_NOWAIT, readData, 24, NULL, 0, &_CdAlignReadBuffer, _rd_intr_data) < 0) { // The Sony function was broken here: It doesn't set a callback, which will cause the library to enter a deadlocked state.
255  CdCallbackNum = 0;
256  cbSema = 0;
257  SignalSema(nCmdSemaId);
258  return 0;
259  }
260 
261  // Old versions have this extra SignalSema call here.
262  // SignalSema(nCmdSemaId);
263  return 1;
264 }
265 #endif
266 
267 #ifdef F_sceCdReadCDDA
268 int sceCdReadCDDA(u32 lbn, u32 nsectors, void *buf, sceCdRMode *rm)
269 {
270  unsigned int sector_size;
271 
273  return 0;
274  if (_CdCheckNCmd(CD_NCMD_CDDAREAD) == 0)
275  return 0;
276 
277  readData[0] = lbn;
278  readData[1] = nsectors;
279  readData[2] = (u32)buf;
280  readData[3] = (rm->trycount) | (rm->spindlctrl << 8) | (rm->datapattern << 16);
281  readData[4] = (u32)_rd_intr_data;
282 
283  /* Calculate the size of the read buffer. */
284  switch (rm->datapattern) {
285  case SCECdSecS2368:
286  sector_size = 2368;
287  break;
288  case SCECdSecS2448:
289  sector_size = 2448;
290  break;
291  default:
292  sector_size = 2352;
293  }
294 
295  sceSifWriteBackDCache(buf, nsectors * sector_size);
296 
297  CdCallbackNum = CD_NCMD_CDDAREAD;
298  cbSema = 1;
299 
300  if (sceSifCallRpc(&clientNCmd, CD_NCMD_CDDAREAD, SIF_RPC_M_NOWAIT, readData, 24, NULL, 0, &_CdAlignReadBuffer, _rd_intr_data) < 0) {
301  CdCallbackNum = 0;
302  cbSema = 0;
303  SignalSema(nCmdSemaId);
304  return 0;
305  }
306 
307  // Old versions have this extra SignalSema call here.
308  // SignalSema(nCmdSemaId);
309  return 1;
310 }
311 #endif
312 
313 #ifdef F_sceCdGetToc
314 int sceCdGetToc(u8 *toc)
315 {
316  u8 *tocPtr, *tocEnd;
317 
318  if (_CdCheckNCmd(CD_NCMD_GETTOC) == 0)
319  return 0;
320 
321  getTocSendBuff[0] = (u32)tocBuff;
322  sceSifWriteBackDCache(tocBuff, 2064);
323 
324  if (sceSifCallRpc(&clientNCmd, CD_NCMD_GETTOC, 0, getTocSendBuff, 12, nCmdRecvBuff, 8, NULL, NULL) < 0) {
325  SignalSema(nCmdSemaId);
326  return 0;
327  }
328 
329  tocPtr = UNCACHED_SEG(tocBuff);
330  tocEnd = tocPtr + 1024;
331  if (*(u32 *)(nCmdRecvBuff + 4)) {
332  do {
333  memcpy(toc, tocPtr, 32);
334  tocPtr += 32;
335  toc += 32;
336  } while (tocPtr < tocEnd);
337  } else {
338  tocEnd = tocPtr + 2048;
339 
340  do {
341  memcpy(toc, tocPtr, 32);
342  tocPtr += 32;
343  toc += 32;
344  } while (tocPtr < tocEnd);
345 
346  memcpy(toc, tocPtr, 16);
347  }
348 
349  SignalSema(nCmdSemaId);
350  return *(int *)UNCACHED_SEG(nCmdRecvBuff);
351 }
352 #endif
353 
354 #ifdef F_sceCdSeek
355 int sceCdSeek(u32 lbn)
356 {
358  return 0;
359  if (_CdCheckNCmd(CD_NCMD_SEEK) == 0)
360  return 0;
361 
362  seekSector = lbn;
363 
364  CdCallbackNum = CD_NCMD_SEEK;
365  cbSema = 1;
366  if (sceSifCallRpc(&clientNCmd, CD_NCMD_SEEK, SIF_RPC_M_NOWAIT, &seekSector, 4, NULL, 0, &_CdGenericCallbackFunction, (void *)&CdCallbackNum) < 0) {
367  CdCallbackNum = 0;
368  cbSema = 0;
369  SignalSema(nCmdSemaId);
370  return 0;
371  }
372 
373  // Old versions have this extra SignalSema call here.
374  // SignalSema(nCmdSemaId);
375  return 1;
376 }
377 #endif
378 
379 #ifdef F_sceCdStandby
380 int sceCdStandby(void)
381 {
383  return 0;
384  if (_CdCheckNCmd(CD_NCMD_STANDBY) == 0)
385  return 0;
386 
387  CdCallbackNum = CD_NCMD_STANDBY;
388  cbSema = 1;
389  if (sceSifCallRpc(&clientNCmd, CD_NCMD_STANDBY, SIF_RPC_M_NOWAIT, NULL, 0, NULL, 0, &_CdGenericCallbackFunction, (void *)&CdCallbackNum) < 0) {
390  CdCallbackNum = 0;
391  cbSema = 0;
392  SignalSema(nCmdSemaId);
393  return 0;
394  }
395 
396  // Old versions have this extra SignalSema call here.
397  // SignalSema(nCmdSemaId);
398  return 1;
399 }
400 #endif
401 
402 #ifdef F_sceCdStop
403 int sceCdStop(void)
404 {
406  return 0;
407  if (_CdCheckNCmd(CD_NCMD_STOP) == 0)
408  return 0;
409 
410  CdCallbackNum = CD_NCMD_STOP;
411  cbSema = 1;
412  if (sceSifCallRpc(&clientNCmd, CD_NCMD_STOP, SIF_RPC_M_NOWAIT, NULL, 0, NULL, 0, &_CdGenericCallbackFunction, (void *)&CdCallbackNum) < 0) {
413  CdCallbackNum = 0;
414  cbSema = 0;
415  SignalSema(nCmdSemaId);
416  return 0;
417  }
418 
419  // Old versions have this extra SignalSema call here.
420  // SignalSema(nCmdSemaId);
421  return 1;
422 }
423 #endif
424 
425 #ifdef F_sceCdPause
426 int sceCdPause(void)
427 {
429  return 0;
430  if (_CdCheckNCmd(CD_NCMD_PAUSE) == 0)
431  return 0;
432 
433  CdCallbackNum = CD_NCMD_PAUSE;
434  cbSema = 1;
435  if (sceSifCallRpc(&clientNCmd, CD_NCMD_PAUSE, SIF_RPC_M_NOWAIT, NULL, 0, NULL, 0, &_CdGenericCallbackFunction, (void *)&CdCallbackNum) < 0) {
436  CdCallbackNum = 0;
437  cbSema = 0;
438  SignalSema(nCmdSemaId);
439  return 0;
440  }
441 
442  // Old versions have this extra SignalSema call here.
443  // SignalSema(nCmdSemaId);
444  return 1;
445 }
446 #endif
447 
448 #ifdef F_sceCdApplyNCmd
449 int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
450 {
452  return 0;
453  if (_CdCheckNCmd(CD_NCMD_NCMD) == 0)
454  return 0;
455 
456  nCmdSendBuff.ncmd.cmdNum = cmdNum;
457  nCmdSendBuff.ncmd.inBuffSize = inBuffSize;
458  memset(nCmdSendBuff.ncmd.inBuff, 0, 16);
459  if (inBuff)
460  memcpy(nCmdSendBuff.ncmd.inBuff, inBuff, inBuffSize);
461 
462  if (sceSifCallRpc(&clientNCmd, CD_NCMD_NCMD, 0, &nCmdSendBuff, 20, nCmdRecvBuff, 16, NULL, NULL) < 0) {
463  SignalSema(nCmdSemaId);
464  return 0;
465  }
466 
467  SignalSema(nCmdSemaId);
468  return *(int *)UNCACHED_SEG(nCmdRecvBuff);
469 }
470 #endif
471 
472 #ifdef F_sceCdReadIOPMem
473 int sceCdReadIOPMem(u32 lbn, u32 sectors, void *buf, sceCdRMode *mode)
474 {
476  return 0;
477  if (_CdCheckNCmd(CD_NCMD_READIOPMEM) == 0)
478  return 0;
479 
480  readData[0] = lbn;
481  readData[1] = sectors;
482  readData[2] = (u32)buf;
483  readData[3] = (mode->trycount) | (mode->spindlctrl << 8) | (mode->datapattern << 16);
484  readData[4] = (u32)_rd_intr_data;
485  readData[5] = (u32)&curReadPos;
486 
487  CdCallbackNum = CD_NCMD_READIOPMEM;
488  cbSema = 1;
489  if (sceSifCallRpc(&clientNCmd, CD_NCMD_READIOPMEM, SIF_RPC_M_NOWAIT, readData, 24, NULL, 0, &_CdGenericCallbackFunction, (void *)&CdCallbackNum) < 0) {
490  CdCallbackNum = 0;
491  cbSema = 0;
492  SignalSema(nCmdSemaId);
493  return 0;
494  }
495 
496  if (CdDebug > 0)
497  printf("sceCdread end\n");
498 
499  // Old versions have this extra SignalSema call here.
500  // SignalSema(nCmdSemaId);
501  return 1;
502 }
503 #endif
504 
505 #ifdef F_sceCdNCmdDiskReady
506 int sceCdNCmdDiskReady(void)
507 {
508  if (_CdCheckNCmd(CD_NCMD_DISKREADY) == 0)
509  return 0;
510 
511  if (sceSifCallRpc(&clientNCmd, CD_NCMD_DISKREADY, 0, NULL, 0, &nCmdRecvBuff, 4, NULL, NULL) < 0) {
512  SignalSema(nCmdSemaId);
513  return 0;
514  }
515 
516  SignalSema(nCmdSemaId);
517  return *(int *)UNCACHED_SEG(nCmdRecvBuff);
518 }
519 #endif
520 
521 #ifdef F_sceCdReadChain
522 int sceCdReadChain(sceCdRChain *readChain, sceCdRMode *mode)
523 {
524  int chainNum, i, sectorType;
525 
527  return 0;
528  if (_CdCheckNCmd(CD_NCMD_READCHAIN) == 0)
529  return 0;
530 
531  if (CdDebug > 0)
532  printf("call sceCdReadChain cmd 0\n");
533 
534  for (chainNum = 0; chainNum < 64; chainNum++) {
535  if (readChain[chainNum].lbn == 0xFFFFFFFF ||
536  readChain[chainNum].sectors == 0xFFFFFFFF || readChain[chainNum].buffer == 0xFFFFFFFF)
537  break;
538  readChainData[chainNum].lbn = readChain[chainNum].lbn;
539  readChainData[chainNum].sectors = readChain[chainNum].sectors;
540  readChainData[chainNum].buffer = readChain[chainNum].buffer;
541  }
542  // store 'end of read-chain' data in chain
543  readChainData[chainNum].lbn = 0xFFFFFFFF;
544  readChainData[chainNum].sectors = 0xFFFFFFFF;
545  readChainData[chainNum].buffer = 0xFFFFFFFF;
546 
547  // store read mode and read position in read chain data
548  readChainData[65].lbn = (mode->trycount) | (mode->spindlctrl << 8) | (mode->datapattern << 16);
549  readChainData[65].sectors = (u32)&curReadPos;
550 
551  if (mode->datapattern == SCECdSecS2328)
552  sectorType = 2328;
553  else if (mode->datapattern == SCECdSecS2340)
554  sectorType = 2340;
555  else
556  sectorType = 2048;
557 
558  curReadPos = 0;
559  if (CdDebug > 0)
560  printf("call sceCdReadChain cmd 1\n");
561 
562  for (i = 0; i < chainNum; i++) {
563  // if memory is on EE, make sure its not cached
564  if ((readChainData[i].buffer & 1) == 0) {
565  if (CdDebug > 0)
566  printf("sceSifWriteBackDCache addr= 0x%08x size= %d, sector= %d\n",
567  readChainData[i].buffer, readChainData[i].sectors * sectorType,
568  readChainData[i].lbn);
569  sceSifWriteBackDCache((void *)(readChainData[i].buffer),
570  readChainData[i].sectors * sectorType);
571  }
572  }
573 
574  sceSifWriteBackDCache(&curReadPos, 4);
575 
576  if (CdDebug > 0)
577  printf("call sceCdReadChain cmd 2\n");
578  CdCallbackNum = CD_NCMD_READCHAIN;
579  cbSema = 1;
580  if (sceSifCallRpc(&clientNCmd, CD_NCMD_READCHAIN, SIF_RPC_M_NOWAIT, readChainData, 788, NULL, 0, &_CdGenericCallbackFunction, (void *)&CdCallbackNum) < 0) {
581  CdCallbackNum = 0;
582  cbSema = 0;
583  SignalSema(nCmdSemaId);
584  return 0;
585  }
586 
587  if (CdDebug > 0)
588  printf("sceCdread end\n");
589 
590  // Old versions have this extra SignalSema call here.
591  // SignalSema(nCmdSemaId);
592  return 1;
593 }
594 #endif
595 
596 #ifdef F_sceCdGetReadPos
597 u32 sceCdGetReadPos(void)
598 {
599  if (CdCallbackNum == CD_NCMD_READ) {
600  return *(u32 *)UNCACHED_SEG(curReadPos);
601  }
602  return 0;
603 }
604 #endif
605 
606 /* Stream Functions */
607 
608 #ifdef F_sceCdStStart
609 int sceCdStStart(u32 lbn, sceCdRMode *mode)
610 {
611  streamStatus = 1;
612  return sceCdStream(lbn, 0, NULL, CDVD_ST_CMD_START, mode);
613 }
614 #endif
615 
616 #ifdef F_sceCdStRead
617 int sceCdStRead(u32 sectorType, u32 *buffer, u32 mode, u32 *error)
618 {
619  int ret, i;
620 
621  *error = 0;
622  if (CdDebug > 0)
623  printf("sceCdStRead call read size=%d mode=%d\n", sectorType, mode);
624  if (streamStatus == 0)
625  return 0;
626  sceSifWriteBackDCache(buffer, sectorType * 2048);
627 
628  // read only data currently in stream buffer
629  if (mode == STMNBLK) {
630  ret = sceCdStream(0, sectorType, buffer, CDVD_ST_CMD_READ, &dummyMode);
631  *error = ret >> 16;
632  return ret & 0xFFFF;
633  }
634  // do block reads until all data is read, or error occurs
635  for (i = 0; (u32)i < sectorType;) {
636  int err, sectorReadSize;
637 
638  ret = sceCdStream(0, sectorType - i, (buffer + (i * 2048)), CDVD_ST_CMD_READ, &dummyMode);
639  sectorReadSize = ret & 0xFFFF;
640  i += sectorReadSize;
641  err = ret >> 16;
642 
643  if (err) {
644  *error = err;
645  if (CdDebug > 0)
646  printf("sceCdStRead BLK Read cur_size= %d read_size= %d req_size= %d err 0x%x\n", i,
647  sectorReadSize, sectorType, err);
648 
649  if (sectorReadSize == 0)
650  break;
651  }
652  }
653 
654  if (CdDebug > 0)
655  printf("sceCdStRead BLK Read Ended\n");
656  return i;
657 }
658 #endif
659 
660 #ifdef F_sceCdStStop
661 int sceCdStStop(void)
662 {
663  streamStatus = 0;
664  return sceCdStream(0, 0, NULL, CDVD_ST_CMD_STOP, &dummyMode);
665 }
666 #endif
667 
668 #ifdef F_sceCdStSeek
669 int sceCdStSeek(u32 lbn)
670 {
671  return sceCdStream(lbn, 0, NULL, CDVD_ST_CMD_SEEK, &dummyMode);
672 }
673 #endif
674 
675 #ifdef F_sceCdStInit
676 int sceCdStInit(u32 buffSize, u32 numBuffers, void *buf)
677 {
678  streamStatus = 0;
679  return sceCdStream(buffSize, numBuffers, buf, CDVD_ST_CMD_INIT, &dummyMode);
680 }
681 #endif
682 
683 #ifdef F_sceCdStStat
684 int sceCdStStat(void)
685 {
686  streamStatus = 0;
687  return sceCdStream(0, 0, NULL, CDVD_ST_CMD_STAT, &dummyMode);
688 }
689 #endif
690 
691 #ifdef F_sceCdStPause
692 int sceCdStPause(void)
693 {
694  streamStatus = 0;
695  return sceCdStream(0, 0, NULL, CDVD_ST_CMD_PAUSE, &dummyMode);
696 }
697 #endif
698 
699 #ifdef F_sceCdStResume
700 int sceCdStResume(void)
701 {
702  streamStatus = 0;
703  return sceCdStream(0, 0, NULL, CDVD_ST_CMD_RESUME, &dummyMode);
704 }
705 #endif
706 
708 #ifdef F_sceCdStream
709 int sceCdStream(u32 lbn, u32 nsectors, void *buf, CdvdStCmd_t cmd, sceCdRMode *rm)
710 {
711  if (_CdCheckNCmd(15) == 0)
712  return 0;
713 
714  if (CdDebug > 0)
715  printf("call sceCdreadstm call\n");
716 
717  readStreamData[0] = lbn;
718  readStreamData[1] = nsectors;
719  readStreamData[2] = (u32)buf;
720  readStreamData[3] = cmd;
721  if (rm) {
722  readStreamData[4] = (rm->trycount) | (rm->spindlctrl << 8) | (rm->datapattern << 16);
723  }
724  if (CdDebug > 0)
725  printf("call sceCdreadstm cmd\n");
726 
727  if (sceSifCallRpc(&clientNCmd, CD_NCMD_STREAM, 0, readStreamData, 20, nCmdRecvBuff, 4, NULL, NULL) < 0) {
728  SignalSema(nCmdSemaId);
729  return 0;
730  }
731 
732  if (CdDebug > 0)
733  printf("sceCdread end\n");
734  SignalSema(nCmdSemaId);
735  return *(int *)UNCACHED_SEG(nCmdRecvBuff);
736 }
737 #endif
738 
739 #ifdef F_sceCdCddaStream
740 int sceCdCddaStream(u32 lbn, u32 nsectors, void *buf, CdvdStCmd_t cmd, sceCdRMode *rm)
741 {
742  unsigned int sector_size;
743 
744  if (_CdCheckNCmd(17) == 0)
745  return cmd < CDVD_ST_CMD_INIT ? -1 : 0;
746 
747  if (rm->datapattern == SCECdSecS2368)
748  sector_size = 2368;
749  else
750  sector_size = 2352;
751 
752  readStreamData[0] = lbn;
753  readStreamData[1] = nsectors * sector_size;
754  readStreamData[2] = (u32)buf;
755  readStreamData[3] = cmd;
756  readStreamData[4] = (rm->trycount) | (rm->spindlctrl << 8) | (rm->datapattern << 16);
757 
758  if (cmd == CDVD_ST_CMD_INIT)
759  readStreamData[2] = (u32)cdda_st_buf;
760 
761  *cdda_st_buf = 0;
762 
763  if (sceSifCallRpc(&clientNCmd, CD_NCMD_CDDASTREAM, 0, readStreamData, 20, nCmdRecvBuff, 4, NULL, NULL) < 0) {
764  SignalSema(nCmdSemaId);
765  return cmd < CDVD_ST_CMD_INIT ? -1 : 0;
766  }
767 
768  SignalSema(nCmdSemaId);
769  return *(int *)UNCACHED_SEG(nCmdRecvBuff);
770 }
771 #endif
772 
773 #ifdef F_sceCdSync
774 int sceCdSync(int mode)
775 {
776  // block till completed mode
777  if (mode == 0) {
778  if (CdDebug > 0)
779  printf("N cmd wait\n");
780 
781  // wait till callback semaphore and client are ready
782  while (cbSema || sceSifCheckStatRpc(&clientNCmd))
783  ;
784  return 0;
785  }
786  // check status and return
787  if (cbSema || sceSifCheckStatRpc(&clientNCmd))
788  return 1;
789 
790  return 0;
791 }
792 #endif
793 
799 #ifdef F__CdCheckNCmd
800 int _CdCheckNCmd(int cmd)
801 {
802  _CdSemaInit();
803  if (PollSema(nCmdSemaId) != nCmdSemaId) {
804  if (CdDebug > 0)
805  printf("Ncmd fail sema cmd:%d keep_cmd:%d\n", cmd, nCmdNum);
806  return 0;
807  }
808 
809  nCmdNum = cmd;
810  ReferThreadStatus(CdThreadId, &CdThreadParam);
811  if (sceCdSync(1)) {
812  SignalSema(nCmdSemaId);
813  return 0;
814  }
815 
816  sceSifInitRpc(0);
818  memset(&clientNCmd, 0, sizeof(clientNCmd));
819  // if already bound, return ok
820  if (clientNCmd.server)
821  return 1;
822  // bind rpc for n-commands
823  while (1) {
824  if (sceSifBindRpc(&clientNCmd, CD_SERVER_NCMD, 0) < 0) {
825  if (CdDebug > 0)
826  printf("Libcdvd bind err N CMD\n");
827  }
828  if (clientNCmd.server != 0)
829  break;
830 
831  nopdelay();
832  }
833  if (!initVersionCdvdfsv)
834  {
835  struct _cdvd_read_data_1400 tmpbuf;
836  int i;
837  int eq_count;
838  struct _cdvd_read_data_1400 *uncached;
839 
840  uncached = UNCACHED_SEG(_rd_intr_data);
841  // Attempt to determine the size of the CDVD read unaligned buffer
842  readData[0] = 0;
843  readData[1] = 0;
844  readData[2] = (u32)NULL;
845  readData[3] = 0;
846  readData[4] = (u32)_rd_intr_data;
847 
848  if (sceSifCallRpc(&clientNCmd, CD_NCMD_CDDAREAD, 0, readData, sizeof(readData), NULL, 0, 0, 0) < 0)
849  return 0;
850 
851  // Nothing is read, so ensure that is the case
852  if (uncached->size1 || uncached->dest1 || uncached->size2 || uncached->dest2)
853  return 0;
854  tmpbuf = *uncached;
855  for (i = 0; i < sizeof(*uncached); i += 1)
856  ((u8 *)uncached)[i] ^= 0xFF;
857 
858  if (sceSifCallRpc(&clientNCmd, CD_NCMD_CDDAREAD, 0, readData, sizeof(readData), NULL, 0, 0, 0) < 0)
859  return 0;
860  // Nothing is read, so ensure that is the case
861  if (uncached->size1 || uncached->dest1 || uncached->size2 || uncached->dest2)
862  return 0;
863 
864  eq_count = 0;
865  for (i = 0; i < sizeof(*uncached); i += 1)
866  eq_count += (((u8 *)uncached)[i] == ((u8 *)&tmpbuf)[i]) ? 1 : 0;
867  initVersionCdvdfsv = (eq_count > sizeof(struct _cdvd_read_data_1300)) ? 0x200 : 0x104;
868  }
869  return 1;
870 }
871 #endif
872 
873 #ifdef F_sceCdReadKey
874 int sceCdReadKey(unsigned char arg1, unsigned char arg2, unsigned int command, unsigned char *key)
875 {
876  int result;
877 
878  if (_CdCheckNCmd(CD_NCMD_READ_KEY) == 0)
879  return 0;
880 
881  nCmdSendBuff.readKey.arg1 = arg1;
882  nCmdSendBuff.readKey.arg2 = arg2;
883  nCmdSendBuff.readKey.command = command;
884 
885  if (sceSifCallRpc(&clientNCmd, CD_NCMD_READ_KEY, 0, &nCmdSendBuff, 0xC, nCmdRecvBuff, 0x18, NULL, NULL) >= 0) {
886  memcpy(key, UNCACHED_SEG(&nCmdRecvBuff[4]), 16);
887  result = 1;
888  } else {
889  SignalSema(nCmdSemaId);
890  result = 0;
891  }
892 
893  return result;
894 }
895 #endif
nCmdSendParams_t
Definition: ncmd.c:72
kernel.h
SIF_RPC_M_NOWAIT
#define SIF_RPC_M_NOWAIT
Definition: sifrpc-common.h:23
libcdvd-rpc.h
sceCdSync
int sceCdSync(int mode)
Definition: cdi.c:109
sceCdRChain
Definition: libcdvd-common.h:245
sceCdReadKey
int sceCdReadKey(unsigned char arg1, unsigned char arg2, unsigned int command, unsigned char *key)
cdvdNcmdParam
Definition: libcdvd-rpc.h:48
sceCdNCmdDiskReady
int sceCdNCmdDiskReady(void)
sceCdRead
int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
Definition: cdi.c:98
sceCdRChain::sectors
u32 sectors
Definition: libcdvd-common.h:250
sceCdRMode::trycount
u8 trycount
Definition: libcdvd-common.h:236
sceCdStandby
int sceCdStandby(void)
Definition: cdi.c:147
toc
static cdda_toc toc
Definition: cdrom.c:52
sceCdStInit
int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
Definition: cdi.c:167
libcdvd.h
iopcontrol.h
CD_NCMD_CMDS
CD_NCMD_CMDS
Definition: ncmd.c:51
sceCdStSeek
int sceCdStSeek(u32 lbn)
Definition: cdi.c:197
sceCdStRead
int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
Definition: cdi.c:179
sceCdApplyNCmd
int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
Definition: cdvdman.c:6079
sceCdRChain::lbn
u32 lbn
Definition: libcdvd-common.h:248
sceCdStStart
int sceCdStStart(u32 lbn, sceCdRMode *mode)
Definition: cdi.c:202
sceCdReadChain
int sceCdReadChain(sceCdRChain *tag, sceCdRMode *mode)
Definition: cdvdman.c:7038
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
sceCdStStop
int sceCdStStop(void)
Definition: cdi.c:214
SCECdNotReady
@ SCECdNotReady
Definition: libcdvd-common.h:156
sceCdStPause
int sceCdStPause(void)
Definition: cdi.c:219
sceCdReadIOPMem
int sceCdReadIOPMem(u32 lbn, u32 sectors, void *buf, sceCdRMode *mode)
HasIopRebootedSinceLastCall
static int HasIopRebootedSinceLastCall(void)
Definition: iopcontrol.h:47
stdio.h
sceCdPause
int sceCdPause(void)
Definition: cdi.c:93
CD_NCMD_READCHAIN
@ CD_NCMD_READCHAIN
Definition: ncmd.c:67
cdvdReadKeyParam
Definition: libcdvd-rpc.h:55
sceCdStop
int sceCdStop(void)
Definition: cdi.c:157
sceCdGetReadPos
u32 sceCdGetReadPos(void)
Definition: cdi.c:45
CD_SERVER_NCMD
#define CD_SERVER_NCMD
Definition: ncmd.c:33
sceCdRMode::datapattern
u8 datapattern
Definition: libcdvd-common.h:240
t_SifRpcClientData
Definition: sifrpc-common.h:134
sceCdSeek
int sceCdSeek(u32 lbn)
Definition: cdi.c:142
__attribute__
Definition: gif_registers.h:38
sceCdRMode
Definition: libcdvd-common.h:233
sceCdStStat
int sceCdStStat(void)
Definition: cdi.c:209
STMNBLK
@ STMNBLK
Definition: libcdvd-common.h:365
_cdvd_read_data_1400
Definition: ncmd.c:128
sceCdGetToc
int sceCdGetToc(u8 *toc)
Definition: cdi.c:57
sceCdStResume
int sceCdStResume(void)
Definition: cdi.c:224
_cdvd_read_data_1300
Definition: ncmd.c:137
sceCdRMode::spindlctrl
u8 spindlctrl
Definition: libcdvd-common.h:238
sceCdRChain::buffer
u32 buffer
Definition: libcdvd-common.h:252
CdvdStCmd_t
CdvdStCmd_t
Definition: ncmd.c:36