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