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