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