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