PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
cdvdman.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12
13#include <cdvdman.h>
14
15#include <cdvd-ioctl.h>
16#include <dev5_mmio_hwport.h>
17#include <errno.h>
18#include <hdd-ioctl.h>
19#include <kerr.h>
20
21IRX_ID("cdvd_driver", 2, 38);
22// Based on the module from SCE SDK 3.1.0.
23
24extern struct irx_export_table _exp_cdvdman;
25
27{
28 int m_number;
29 int m_parent;
30 int m_extent;
31 char m_name[32];
33
34typedef struct cdvdman_fhinfo_
35{
36 u32 m_file_lsn;
37 u32 m_read_pos;
38 u32 m_file_size;
39 u32 m_filemode;
40 int m_fd_flags;
41 int m_fd_layer;
42 int m_cache_file_fd;
43 u8 *m_fd_rcvbuf;
44 u32 m_fd_rbsize;
45 void *m_max_cluster;
46 int m_sector_count_total;
47 int m_cluster_cur;
49
50typedef struct cdvdman_pathtbl_
51{
52 int m_cache_path_sz;
53 int m_lsn;
54 unsigned int m_nsec;
55 int m_layer;
56 unsigned int m_cache_hit_count;
58
60{
61 sceCdlFILE m_file_struct;
62 int m_flags;
64
65typedef struct iso9660_desc_
66{
67 // cppcheck-suppress unusedStructMember
68 unsigned char m_type[1];
69 unsigned char m_id[5];
70 // cppcheck-suppress unusedStructMember
71 unsigned char m_version[1];
72 // cppcheck-suppress unusedStructMember
73 unsigned char m_unused1[1];
74 // cppcheck-suppress unusedStructMember
75 unsigned char m_system_id[32];
76 // cppcheck-suppress unusedStructMember
77 unsigned char m_volume_id[32];
78 // cppcheck-suppress unusedStructMember
79 unsigned char m_unused2[8];
80 // cppcheck-suppress unusedStructMember
81 unsigned char m_volume_space_size[8];
82 // cppcheck-suppress unusedStructMember
83 unsigned char m_unused3[32];
84 // cppcheck-suppress unusedStructMember
85 unsigned char m_volume_set_size[4];
86 // cppcheck-suppress unusedStructMember
87 unsigned char m_volume_sequence_number[4];
88 // cppcheck-suppress unusedStructMember
89 unsigned char m_logical_block_size[4];
90 // cppcheck-suppress unusedStructMember
91 unsigned char m_path_table_size[8];
92 unsigned char m_type_l_path_table[4];
93 // cppcheck-suppress unusedStructMember
94 unsigned char m_opt_type_l_path_table[4];
95 // cppcheck-suppress unusedStructMember
96 unsigned char m_type_m_path_table[4];
97 // cppcheck-suppress unusedStructMember
98 unsigned char m_opt_type_m_path_table[4];
99 // cppcheck-suppress unusedStructMember
100 unsigned char m_root_directory_record[34];
101 // cppcheck-suppress unusedStructMember
102 unsigned char m_volume_set_id[128];
103 // cppcheck-suppress unusedStructMember
104 unsigned char m_publisher_id[128];
105 // cppcheck-suppress unusedStructMember
106 unsigned char m_preparer_id[128];
107 // cppcheck-suppress unusedStructMember
108 unsigned char m_application_id[128];
109 // cppcheck-suppress unusedStructMember
110 unsigned char m_copyright_file_id[37];
111 // cppcheck-suppress unusedStructMember
112 unsigned char m_abstract_file_id[37];
113 // cppcheck-suppress unusedStructMember
114 unsigned char m_bibliographic_file_id[37];
115 // cppcheck-suppress unusedStructMember
116 unsigned char m_creation_date[17];
117 // cppcheck-suppress unusedStructMember
118 unsigned char m_modification_date[17];
119 // cppcheck-suppress unusedStructMember
120 unsigned char m_expiration_date[17];
121 // cppcheck-suppress unusedStructMember
122 unsigned char m_effective_date[17];
123 // cppcheck-suppress unusedStructMember
124 unsigned char m_file_structure_version[1];
125 // cppcheck-suppress unusedStructMember
126 unsigned char m_unused4[1];
127 // cppcheck-suppress unusedStructMember
128 unsigned char m_application_data[512];
129 // cppcheck-suppress unusedStructMember
130 unsigned char m_unused5[653];
132
133typedef struct iso9660_path_
134{
135 unsigned char m_name_len[2];
136 unsigned char m_extent[4];
137 unsigned char m_parent[2];
138 unsigned char m_name[];
140
141typedef struct iso9660_dirent_
142{
143 unsigned char m_length[1];
144 unsigned char m_ext_attr_length[1];
145 unsigned char m_extent[8];
146 unsigned char m_size[8];
147 unsigned char m_date[7];
148 unsigned char m_flags[1];
149 unsigned char m_file_unit_size[1];
150 unsigned char m_interleave[1];
151 unsigned char m_volume_sequence_number[4];
152 unsigned char m_name_len[1];
153 unsigned char m_name[];
155
156static int cdrom_init(iop_device_t *dev);
157void cdvdman_termcall(int with_stop);
158static int cdrom_deinit();
159static int cdrom_dopen(iop_file_t *f, const char *dirname);
160static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf);
161static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf);
162static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4);
163static int cdrom_close(iop_file_t *f);
164static int cdrom_read(iop_file_t *f, void *buf, int nbytes);
165static int cdrom_ioctl(iop_file_t *f, int arg, void *param);
166static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen);
167static int
168cdrom_devctl(iop_file_t *f, const char *, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen);
169static int cdrom_lseek(iop_file_t *f, int offset, int pos);
170static int cdrom_nulldev();
171static s64 cdrom_nulldev64();
172static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer);
173static int sceCdSearchDir(char *dirname, int layer);
174static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer);
175static int cdvdman_cmpname(const char *p, const char *q);
176static int CD_newmedia(int arg);
177static int cdvdman_finddir(int target_parent, const char *target_name);
178static int CD_cachefile(int dsec, int layer);
179static int disc_read(int size, int loc, void *buffer, int layer);
180static int path_tbl_init(u32 blocks, char *fname, int action);
181unsigned int optimized_memcpy(char *dst, const char *src, unsigned int n);
182static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *), void *arg);
183static int vCancelAlarm(unsigned int (*alarm_cb)(void *), void *arg);
184static int vSetEventFlag(int ef, u32 bits);
185static int vDelayThread(int usec);
186static int DvdDual_infochk();
187static void cdvdman_init();
188static void cdvdman_write_scmd(cdvdman_internal_struct_t *s);
189static int intrh_dma_3(cdvdman_internal_struct_t *s);
190static int cdvdman_mediactl(int code);
191static int cdvdman_ncmd_sender_06();
192static int cdvdman_gettoc(u8 *toc);
193static int cdvdman_isdvd();
194static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func);
195static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data);
196static void Read2intrCDVD(int read2_flag);
197static int sceCdGetMVersion(u8 *buffer, u32 *status);
198static int cdvdman_scmd_sender_03_48(u8 *buf, u32 *status);
199static int cdvdman_scmd_sender_3B(int arg1);
200#ifdef CDVD_VARIANT_DNAS
201static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3);
202#endif
203
204static char g_cdvdman_cache_name[256] = "host0:";
205static int g_cdvdman_cache_sector_size_count = 1;
206static int g_cdvdman_srchspd = 0;
207static int g_cdvdman_spinctl = -1;
208static int g_cdvdman_spinnom = -1;
209static int g_cdvdman_trycnt = -1;
210static int g_cdvdman_iocache = 0;
211static unsigned int g_cdvdman_lcn_offset = 0;
212static unsigned int g_cdvdman_numbytes_offset = 0;
213static int g_cdvdman_strmerr = 0;
214static iop_device_ops_t g_cdvdman_cddev_ops = {
215 &cdrom_init,
216 &cdrom_deinit,
217 (void *)&cdrom_nulldev,
218 &cdrom_open,
219 &cdrom_close,
220 &cdrom_read,
221 (void *)&cdrom_nulldev,
222 &cdrom_lseek,
223 &cdrom_ioctl,
224 (void *)&cdrom_nulldev,
225 (void *)&cdrom_nulldev,
226 (void *)&cdrom_nulldev,
227 &cdrom_dopen,
228 &cdrom_close,
229 &cdrom_dread,
230 &cdrom_getstat,
231 (void *)&cdrom_nulldev,
232 (void *)&cdrom_nulldev,
233 (void *)&cdrom_nulldev,
234 (void *)&cdrom_nulldev,
235 (void *)&cdrom_nulldev,
236 (void *)&cdrom_nulldev,
237 (void *)&cdrom_nulldev64,
238 &cdrom_devctl,
239 (void *)&cdrom_nulldev,
240 (void *)&cdrom_nulldev,
241 &cdrom_ioctl2,
242};
243static iop_device_t g_cdvdman_cddev = {"cdrom", IOP_DT_FSEXT | IOP_DT_FS, 1, "CD-ROM ", &g_cdvdman_cddev_ops};
244static int g_cdvdman_sync_timeout = 15000;
245static int g_cdvdman_stream_timeout = 5000;
246#ifdef CDVD_VARIANT_DNAS
247static iop_sys_clock_t g_readid_systemtime = {0, 0};
248#endif
249static int g_verbose_level = 0;
250static cdvdman_pathtbl_t *g_cdvdman_pathtbl = NULL;
251static unsigned int g_cache_count = 0;
252static unsigned int g_cache_table = 0;
253static unsigned int g_cdvdman_pathtblsize = 0;
254static int g_cache_path_size = 0;
255static int g_cache_path_fd = -1;
256static int g_cdvdman_fs_cdsec = 0;
257static int g_cdvdman_fs_layer = -1;
258static int g_cdvdman_fs_cache = 0;
259static int g_cdvdman_fs_base2 = 0;
260static int g_cdvdman_clk_flg = 0;
261static int g_cdvdman_cd36key = 0;
262static int g_cdvdman_ee_rpc_fno = 0;
263static int g_cdvdman_mmode = 0;
264static int g_cdvdman_last_cmdfunc = 0;
265static int g_cdvdman_minver_10700 = 0;
266static int g_cdvdman_minver_20200 = 0;
267static int g_cdvdman_minver_20400 = 0;
268static int g_cdvdman_minver_20800 = 0;
269static int g_cdvdman_emudvd9 = 0;
270static int g_cdvdman_minver_50000 = 0;
271static int g_cdvdman_minver_50200 = 0;
272static int g_cdvdman_minver_50400 = 0;
273static int g_cdvdman_minver_50600 = 0;
274static int g_cdvdman_minver_60000 = 0;
275static int g_cdvdman_minver_60200 = 0;
276static int g_cdvdman_minver_x_model_15 = 0;
277static char *g_masterdisc_header = "PlayStation Master Disc";
278static char g_cdvdman_ncmd = 6;
279static int g_cdvdman_chmedia = 0;
280static int g_cdvdman_chflags[4] = {1, 1, 1, 1};
281static int g_cdvdman_rtindex = 0;
282static int g_cdvdman_retries = 0;
283static u8 *g_cdvdman_ptoc;
284static int g_scmd_evid;
285static void *g_cdvdman_temp_buffer_ptr;
286static int g_sfile_evid;
287static int g_ncmd_evid;
288static int g_fio_fsv_evid;
289static int g_cdvdman_intr_efid;
290static sceCdCBFunc g_cdvdman_user_cb;
291static void *g_cdvdman_poffarg;
292static void (*g_cdvdman_cdstm0cb)(int);
293static sceCdCLOCK g_cdvdman_clock;
294static void (*g_cdvdman_poff_cb)(void *userdata);
295static void (*g_cdvdman_cdstm1cb)(int);
296static int g_cdvdman_cmdfunc;
297static cdvdman_fhinfo_t g_cdvdman_fhinfo[16];
298static char g_cdvdman_sfname[1024];
299static cdvdman_filetbl_entry_t g_cdvdman_filetbl[64];
300static cdvdman_dirtbl_entry_t g_cdvdman_dirtbl[128];
301static int g_cdvdman_pathtblflag;
302static char g_cdvdman_fs_rbuf[2048];
303static int g_cdvdman_readptr;
304static iop_sys_clock_t g_cdvdman_read_alarm_cb_timeout;
305static iop_sys_clock_t g_cdvdman_ncmd_timeout;
306static void *g_cdvdman_readbuf;
307static iop_sys_clock_t g_cdvdman_power_off_timeout;
308static char g_cdvdman_fsvrbuf[42128];
309static cdvdman_internal_struct_t g_cdvdman_istruct;
310
311int _start(int ac, char **av)
312{
313 (void)ac;
314 (void)av;
315
316 if ( RegisterLibraryEntries(&_exp_cdvdman) )
317 {
318 return MODULE_NO_RESIDENT_END;
319 }
320 DelDrv(g_cdvdman_cddev.name);
321 if ( AddDrv(&g_cdvdman_cddev) )
322 {
323 cdrom_deinit();
324 return MODULE_NO_RESIDENT_END;
325 }
326 g_cdvdman_ptoc = (u8 *)&g_cdvdman_fsvrbuf[0x924];
327 g_cdvdman_temp_buffer_ptr = g_cdvdman_fsvrbuf;
328 cdvdman_init();
329#if 0
330 SetRebootTimeLibraryHandlingMode(&_exp_cdvdman, 2);
331#else
332 // Call termination before disabling interrupts
333 _exp_cdvdman.mode &= ~6;
334 _exp_cdvdman.mode |= 2;
335#endif
336 return MODULE_RESIDENT_END;
337}
338
339void *sceGetFsvRbuf(void)
340{
341 return g_cdvdman_fsvrbuf;
342}
343
344static int cdrom_init(iop_device_t *dev)
345{
346 unsigned int i;
348 int scres_unused;
349
350 (void)dev;
351
352 PRINTF("cdvdman Init\n");
353 g_cdvdman_istruct.m_wait_flag = 1;
354 g_cdvdman_istruct.m_scmd_flag = 1;
355 g_cdvdman_istruct.m_read2_flag = 0;
356 g_cdvdman_istruct.m_stream_flag = 0;
357 g_cdvdman_istruct.m_last_error = 0;
358 g_cdvdman_istruct.m_layer_1_lsn = 0;
359 g_cdvdman_istruct.m_use_toc = 0;
360 g_cdvdman_istruct.m_last_read_timeout = 0;
361 g_cdvdman_istruct.m_power_flag = 0;
362 g_cdvdman_istruct.m_current_dvd = 0;
363 g_cdvdman_istruct.m_dual_layer_emulation = 0;
364 g_cdvdman_istruct.m_dec_state = 0;
365 g_cdvdman_istruct.m_check_version = 0;
366 g_cdvdman_istruct.m_dec_shift = 0;
367 g_cdvdman_istruct.m_opo_or_para = -1;
368 g_cdvdman_istruct.m_no_dec_flag = 0;
369 g_cdvdman_istruct.m_cd_inited = 0;
370 g_cdvdman_istruct.m_tray_is_open = 0;
371 g_cdvdman_ee_rpc_fno = 0;
372 g_cdvdman_spinctl = -1;
373 event.attr = EA_MULTI;
374 event.bits = 0;
375 event.option = 0;
376 g_cdvdman_intr_efid = CreateEventFlag(&event);
377 g_scmd_evid = CreateEventFlag(&event);
378 g_ncmd_evid = CreateEventFlag(&event);
379 g_sfile_evid = CreateEventFlag(&event);
380 g_fio_fsv_evid = CreateEventFlag(&event);
381 ClearEventFlag(g_cdvdman_intr_efid, ~0x4);
382 ClearEventFlag(g_cdvdman_intr_efid, ~0x10);
383 SetEventFlag(g_cdvdman_intr_efid, 0x29);
384 SetEventFlag(g_ncmd_evid, 1);
385 SetEventFlag(g_scmd_evid, 1);
386 SetEventFlag(g_sfile_evid, 1);
387 SetEventFlag(g_fio_fsv_evid, 1);
388 g_cdvdman_spinnom = -1;
389 g_cdvdman_trycnt = -1;
390 sceCdSC(0xFFFFFFF3, &scres_unused);
391 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
392 {
393 g_cdvdman_fhinfo[i].m_fd_flags = 0;
394 }
395 return 0;
396}
397
398void cdvdman_termcall(int with_stop)
399{
400 int i;
401 int oldstate;
402 USE_DEV5_MMIO_HWPORT();
403
404 VERBOSE_KPRINTF(1, "CDVD:library Terminate Call %d\n", with_stop);
405 if ( with_stop )
406 {
407 return;
408 }
409 sceCdBreak();
410 sceCdSync(0);
411 if ( g_cdvdman_istruct.m_cd_inited )
412 {
413 cdvdman_ncmd_sender_06();
414 }
415 for ( i = 0; i < 50000; i += 1 )
416 {
417 if ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
418 {
419 break;
420 }
421 DelayThread(100);
422 }
423 sceCdDecSet(0, 0, 0);
424 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
425 {
426 dev5_mmio_hwport->m_dev5_reg_007 = 1;
427 }
428 dmac_ch_set_chcr(3, 0);
429 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
430 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
431 DisableIntr(IOP_IRQ_CDVD, &oldstate);
432 ReleaseIntrHandler(IOP_IRQ_CDVD);
433}
434
435static int cdrom_deinit()
436{
437 unsigned int i;
438
439 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
440 {
441 g_cdvdman_fhinfo[i].m_fd_flags = 0;
442 }
443 DeleteEventFlag(g_fio_fsv_evid);
444 DeleteEventFlag(g_cdvdman_intr_efid);
445 DeleteEventFlag(g_ncmd_evid);
446 DeleteEventFlag(g_scmd_evid);
447 DeleteEventFlag(g_sfile_evid);
448 return 0;
449}
450
451static int cdvdman_devready()
452{
453 int i;
454 USE_DEV5_MMIO_HWPORT();
455
456 for ( i = 0; i < 100; i += 1 )
457 {
458 if ( (dev5_mmio_hwport->m_dev5_reg_00A & 1) )
459 {
460 g_cdvdman_iocache = 0;
461 return -EIO;
462 }
463 if ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag && !g_cdvdman_ee_rpc_fno )
464 {
465 return 1;
466 }
467 DelayThread(10000);
468 }
469 return -EBUSY;
470}
471
472static int cdvdman_l0check(int layer)
473{
474 return !layer
475 && (g_cdvdman_istruct.m_dual_layer_emulation || g_cdvdman_istruct.m_opo_or_para == 1 || g_cdvdman_istruct.m_opo_or_para == 2);
476}
477
478static void cdvdman_iormode(sceCdRMode *rmode, int fmode, int layer)
479{
480 rmode->datapattern = SCECdSecS2048;
481 rmode->trycount = (g_cdvdman_trycnt == -1) ? 16 : g_cdvdman_trycnt;
482 if ( cdvdman_l0check(layer) )
483 {
484 if ( g_cdvdman_spinnom == -1 )
485 {
486 rmode->spindlctrl = (fmode == SCECdSpinX1 || fmode == SCECdSpinMx) ? fmode : SCECdSpinStm;
487 return;
488 }
489 if ( fmode != SCECdSpinX1 && fmode != SCECdSpinMx )
490 {
491 rmode->spindlctrl = SCECdSpinStm;
492 return;
493 }
494 }
495 else if ( g_cdvdman_spinnom == -1 )
496 {
497 switch ( fmode )
498 {
499 case SCECdSpinStm:
500 rmode->spindlctrl = SCECdSpinStm;
501 break;
502 case SCECdSpinNom:
503 rmode->spindlctrl = SCECdSpinNom;
504 break;
505 case SCECdSpinX1:
506 rmode->spindlctrl = SCECdSpinX1;
507 break;
508 case SCECdSpinX2:
509 rmode->spindlctrl = SCECdSpinX2;
510 break;
511 case SCECdSpinX4:
512 rmode->spindlctrl = SCECdSpinX4;
513 break;
514 case SCECdSpinX12:
515 rmode->spindlctrl = SCECdSpinX12;
516 break;
517 case SCECdSpinMx:
518 rmode->spindlctrl = SCECdSpinMx;
519 break;
520 default:
521 rmode->spindlctrl = SCECdSpinNom;
522 break;
523 }
524 return;
525 }
526 rmode->spindlctrl = (u8)g_cdvdman_spinnom;
527}
528
529static int cdrom_dopen(iop_file_t *f, const char *dirname)
530{
531 unsigned int i;
532 int is_devready;
533 size_t path_name_ind;
534 int file_lsn_tmp;
535 char path_name[128];
536 u32 efbits;
537
538 VERBOSE_PRINTF(1, "fileIO DOPEN name= %s layer %d\n", dirname, f->unit);
539 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
540 for ( i = 0; (i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0]))) && g_cdvdman_fhinfo[i].m_fd_flags;
541 i += 1 )
542 {
543 }
544 if ( i == (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])) )
545 {
546 SetEventFlag(g_fio_fsv_evid, 1);
547 return -EMFILE;
548 }
549 f->privdata = (void *)i;
550 is_devready = cdvdman_devready();
551 if ( is_devready < 0 )
552 {
553 SetEventFlag(g_fio_fsv_evid, 1);
554 return is_devready;
555 }
556 strncpy(path_name, dirname, sizeof(path_name));
557 if ( !strcmp(path_name, ".") )
558 {
559 strcpy(path_name, "\\.");
560 }
561 path_name_ind = strlen(path_name);
562 path_name_ind -= (path_name_ind >= 2) ? 2 : 0;
563 if ( strcmp(&path_name[path_name_ind], "\\.") )
564 {
565 strcat(path_name, "\\.");
566 }
567 if ( (unsigned int)(f->unit) >= 2 )
568 {
569 PRINTF("open fail name %s\n", path_name);
570 SetEventFlag(g_fio_fsv_evid, 1);
571 return -ENOENT;
572 }
573 g_cdvdman_fhinfo[i].m_file_lsn = 0;
574 g_cdvdman_srchspd = 0;
575 file_lsn_tmp = sceCdSearchDir(path_name, f->unit);
576 if ( file_lsn_tmp < 0 )
577 {
578 PRINTF("open fail directory %s\n", path_name);
579 SetEventFlag(g_fio_fsv_evid, 1);
580 return -ENOENT;
581 }
582 g_cdvdman_fhinfo[i].m_file_lsn = file_lsn_tmp;
583 g_cdvdman_fhinfo[i].m_read_pos = 0;
584 g_cdvdman_fhinfo[i].m_filemode = 0;
585 g_cdvdman_fhinfo[i].m_fd_flags = 1;
586 g_cdvdman_fhinfo[i].m_fd_layer = f->unit;
587 SetEventFlag(g_fio_fsv_evid, 1);
588 return 0;
589}
590
591static void cdvdman_fillstat(void *dummy, iox_stat_t *buf, cdvdman_filetbl_entry_t *fp)
592{
593 unsigned int i;
594
595 (void)dummy;
596
597 buf->attr = 0;
598 buf->private_5 = 0;
599 buf->private_4 = 0;
600 buf->private_3 = 0;
601 buf->private_2 = 0;
602 buf->private_1 = 0;
603 buf->private_0 = 0;
604 buf->hisize = 0;
605 for ( i = 0; i < (sizeof(buf->mtime) / sizeof(buf->mtime[0])); i += 1 )
606 {
607 buf->mtime[i] = fp->m_file_struct.date[i];
608 buf->atime[i] = fp->m_file_struct.date[i];
609 buf->ctime[i] = fp->m_file_struct.date[i];
610 }
611 buf->size = fp->m_file_struct.size;
612 buf->mode = (((fp->m_flags & 2)) ? (FIO_S_IFDIR | FIO_S_IXUSR | FIO_S_IXGRP | FIO_S_IXOTH) : FIO_S_IFREG)
614}
615
616static int cdvdman_cdfname(char *filename)
617{
618 size_t filename_len;
619
620 filename_len = strlen(filename);
621 if ( filename_len >= 3 && !(filename[filename_len - 2] != ';' && filename[filename_len - 1] != '1') )
622 {
623 return 0;
624 }
625 strcat(filename, ";1");
626 return 1;
627}
628
629static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf)
630{
631 int devready_tmp;
633 char filename[128];
634 u32 efbits;
635
636 VERBOSE_PRINTF(1, "fileIO GETSTAT name= %s layer= %d\n", name, f->unit);
637 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
638 devready_tmp = cdvdman_devready();
639 if ( devready_tmp < 0 )
640 {
641 SetEventFlag(g_fio_fsv_evid, 1);
642 return devready_tmp;
643 }
644 strncpy(filename, name, sizeof(filename));
645 if ( !strcmp(filename, ".") )
646 {
647 strcpy(filename, "\\.");
648 }
649 if ( !strcmp(filename, "\\") )
650 {
651 strcpy(filename, "\\.");
652 }
653 if ( !strlen(filename) )
654 {
655 strcpy(filename, "\\.");
656 }
657 g_cdvdman_srchspd = 0;
658 // Unofficial: initialize to 0
659 memset(&fp, 0, sizeof(fp));
660 if (
661 !sceCdLayerSearchFile(&fp.m_file_struct, filename, f->unit)
662 && !(cdvdman_cdfname(filename) && sceCdLayerSearchFile(&fp.m_file_struct, filename, f->unit)) )
663 {
664 PRINTF("open fail name %s\n", name);
665 SetEventFlag(g_fio_fsv_evid, 1);
666 return -ENOENT;
667 }
668 cdvdman_fillstat(filename, buf, &fp);
669 SetEventFlag(g_fio_fsv_evid, 1);
670 return 1;
671}
672
673static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf)
674{
675 int devready_tmp;
678 u32 efbits;
679
680 memset(&fp, 0, sizeof(fp));
681 VERBOSE_PRINTF(1, "fileIO DREAD\n");
682 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
683 devready_tmp = cdvdman_devready();
684 if ( devready_tmp < 0 )
685 {
686 SetEventFlag(g_fio_fsv_evid, 1);
687 return devready_tmp;
688 }
689 fh = &g_cdvdman_fhinfo[(int)f->privdata];
690 g_cdvdman_srchspd = 0;
691 devready_tmp = sceCdReadDir(&fp.m_file_struct, fh->m_file_lsn, fh->m_read_pos, fh->m_fd_layer);
692 if ( devready_tmp < 0 )
693 {
694 SetEventFlag(g_fio_fsv_evid, 1);
695 return -ENOENT;
696 }
697 if ( devready_tmp )
698 {
699 fh->m_read_pos += 1;
700 devready_tmp = strlen(fp.m_file_struct.name);
701 }
702 strncpy(buf->name, fp.m_file_struct.name, sizeof(buf->name));
703 cdvdman_fillstat(fp.m_file_struct.name, &buf->stat, &fp);
704 SetEventFlag(g_fio_fsv_evid, 1);
705 return devready_tmp;
706}
707
708static int cdvd_odcinit(cdvdman_fhinfo_t *fh, int open_or_close, int id)
709{
710 int cache_remove_result;
711 int cache_result;
712 int cache_file_fd_new;
713 u32 file_size_bsr_3;
714 unsigned int file_size_bsr_17;
715 char cache_filename[512];
716 int state;
717 unsigned int ioctl_arg;
718
719 g_cdvdman_iocache = 0;
720 sprintf(
721 cache_filename,
722 "%sCache_%d_%d_%d_%d",
723 g_cdvdman_cache_name,
724 fh->m_fd_layer,
725 (int)fh->m_file_lsn,
726 (int)fh->m_file_size,
727 id);
728 cache_remove_result = 0;
729 VERBOSE_KPRINTF(1, "Cachefile:%s Open_or_Close:%d\n", cache_filename, open_or_close);
730 cache_result = 0;
731 if ( open_or_close )
732 {
733 u32 i;
734
735 CpuSuspendIntr(&state);
736 fh->m_fd_rbsize = g_cdvdman_cache_sector_size_count ? (g_cdvdman_cache_sector_size_count << 11) : 0x800;
737 fh->m_fd_rcvbuf = (u8 *)AllocSysMemory(ALLOC_LAST, fh->m_fd_rbsize, 0);
738 if ( !fh->m_fd_rcvbuf )
739 {
740 VERBOSE_KPRINTF(1, "Rcvbuf MemAlloc Fail\n");
741 CpuResumeIntr(state);
742 return -ENOMEM;
743 }
744 CpuResumeIntr(state);
745 fh->m_cache_file_fd = -1;
746 cache_result = open(cache_filename, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
747 cache_file_fd_new = cache_result;
748 if ( cache_result >= 0 )
749 {
750 u32 file_size_sectors;
751 unsigned int file_size_bsr_6;
752
753 file_size_sectors = (fh->m_file_size >> 11) + ((!!((fh->m_file_size & 0x7FF))));
754 file_size_bsr_3 = (file_size_sectors >> 3) + (!!(file_size_sectors & 7));
755 file_size_bsr_6 = (file_size_bsr_3 >> 3) + (!!((file_size_bsr_3 & 7)));
756 file_size_bsr_17 = (file_size_bsr_6 >> 11) + (!!((file_size_bsr_6 & 0x7FF)));
757 ioctl_arg = (file_size_bsr_17 + file_size_sectors + 8) << 11;
758 for ( i = 0; i < fh->m_fd_rbsize; i += 1 )
759 {
760 fh->m_fd_rcvbuf[i] = 0;
761 }
762 if ( !strncmp(cache_filename, "pfs", 3) )
763 {
764 cache_result = ioctl2(cache_file_fd_new, PIOCALLOC, &ioctl_arg, 4, 0, 0);
765 }
766 }
767 if ( cache_result >= 0 )
768 {
769 cache_result = lseek(cache_file_fd_new, 0, 0);
770 }
771 if ( cache_result >= 0 )
772 {
773 for ( i = 0; i <= 0x7FFF; i += 1 )
774 {
775 ((char *)g_cdvdman_temp_buffer_ptr)[i] = 0;
776 }
777 for ( i = 0; (int)i < (int)(ioctl_arg >> 15); i += 1 )
778 {
779 cache_result = write(cache_file_fd_new, g_cdvdman_temp_buffer_ptr, 0x8000);
780 if ( cache_result != 0x8000 )
781 {
782 if ( cache_result >= 0 )
783 {
784 cache_result = -EIO;
785 }
786 break;
787 }
788 }
789 }
790 if ( cache_result >= 0 )
791 {
792 for ( i = 0; (int)i < (int)((ioctl_arg >> 11) - 0x10 * (ioctl_arg >> 15)); i += 1 )
793 {
794 cache_result = write(cache_file_fd_new, fh->m_fd_rcvbuf, 0x800);
795 if ( cache_result != 0x800 )
796 {
797 if ( cache_result >= 0 )
798 {
799 cache_result = -EIO;
800 }
801 break;
802 }
803 }
804 }
805 }
806 if ( !open_or_close || cache_result < 0 )
807 {
808 if ( fh->m_cache_file_fd != -1 )
809 {
810 cache_remove_result = close(fh->m_cache_file_fd);
811 VERBOSE_KPRINTF(1, "Cache File Close: %d\n", cache_remove_result);
812 if ( cache_remove_result >= 0 )
813 {
814 if ( !strncmp(cache_filename, "pfs", 3) )
815 {
816 cache_remove_result = remove(cache_filename);
817 }
818 else if ( !strncmp(cache_filename, "host", 4) )
819 {
820 cache_remove_result = 0;
821 remove(cache_filename);
822 }
823 VERBOSE_KPRINTF(1, "Cache File %s remove: %d\n", cache_filename, cache_remove_result);
824 }
825 }
826 fh->m_cache_file_fd = -1;
827 fh->m_max_cluster = 0;
828 fh->m_cluster_cur = -1;
829 fh->m_sector_count_total = 0;
830 CpuSuspendIntr(&state);
831 FreeSysMemory(fh->m_fd_rcvbuf);
832 CpuResumeIntr(state);
833 fh->m_fd_rcvbuf = 0;
834 if ( cache_result < 0 )
835 {
836 VERBOSE_KPRINTF(1, "cdvd_odcinit Open Error %d\n", cache_result);
837 }
838 if ( cache_remove_result < 0 )
839 {
840 VERBOSE_KPRINTF(1, "cdvd_odcinit Close Error %d\n", cache_remove_result);
841 }
842 return (!open_or_close) ? cache_remove_result : cache_result;
843 }
844 fh->m_sector_count_total = file_size_bsr_17 << 11;
845 fh->m_cache_file_fd = cache_file_fd_new;
846 fh->m_max_cluster = (void *)file_size_bsr_3;
847 fh->m_cluster_cur = -1;
848 VERBOSE_KPRINTF(1, "Cache File Maked\n");
849 return 0;
850}
851
852static int cdvdman_cache_invalidate(cdvdman_fhinfo_t *fh, int index)
853{
854 u32 i;
855 int fileio_res;
856
857 if ( fh->m_cluster_cur == -1 )
858 {
859 return 0;
860 }
861 fh->m_cluster_cur = -1;
862 for ( i = 0; i < fh->m_fd_rbsize; i += 1 )
863 {
864 fh->m_fd_rcvbuf[i] = 0;
865 }
866 fileio_res = lseek(fh->m_cache_file_fd, 0, 0);
867 if ( fileio_res >= 0 )
868 {
869 for ( i = 0; i < ((unsigned int)fh->m_sector_count_total >> 11); i += 1 )
870 {
871 fileio_res = write(fh->m_cache_file_fd, fh->m_fd_rcvbuf, 0x800);
872 if ( fileio_res < 0 )
873 {
874 break;
875 }
876 }
877 }
878 if ( fileio_res >= 0 )
879 {
880 return fileio_res;
881 }
882 fh->m_fd_flags &= ~4;
883 cdvd_odcinit(fh, 0, index);
884 return fileio_res;
885}
886
887static int cdvdman_invcaches()
888{
889 unsigned int i;
890
891 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
892 {
893 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 4) )
894 {
895 cdvdman_cache_invalidate(&g_cdvdman_fhinfo[i], i);
896 }
897 }
898 return 0;
899}
900
901static int cdrom_internal_cache_read(const iop_file_t *f, int nbytes)
902{
904 s16 readpos_plus_nbytes;
905 unsigned int readpos_plus_nbytes_bsr_14;
906 int readpos_bsr_14;
907 int cluster_cur;
908 unsigned int i;
909
910 fh = &g_cdvdman_fhinfo[(int)f->privdata];
911 if ( cdvdman_devready() < 0 )
912 {
913 g_cdvdman_iocache = 0;
914 return -EBUSY;
915 }
916 if ( fh->m_cluster_cur == -1 )
917 {
918 if ( (void *)(8 * fh->m_fd_rbsize) < fh->m_max_cluster )
919 {
920 fh->m_cluster_cur = (fh->m_read_pos >> 14) & ~0x7;
921 if (
922 lseek(fh->m_cache_file_fd, fh->m_cluster_cur >> 3, 0) < 0
923 || read(fh->m_cache_file_fd, fh->m_fd_rcvbuf, fh->m_fd_rbsize) < 0 )
924 {
925 fh->m_cluster_cur = -1;
926 return -EIO;
927 }
928 }
929 else
930 {
931 fh->m_cluster_cur = -2;
932 }
933 }
934 readpos_plus_nbytes = fh->m_read_pos + nbytes;
935 readpos_plus_nbytes_bsr_14 = (readpos_plus_nbytes >> 14) - (!(readpos_plus_nbytes & 0x3FFF));
936 readpos_bsr_14 = fh->m_read_pos >> 14;
937 VERBOSE_KPRINTF(
938 1, "max_claster %d meta_size_clst %d claster_cur %d\n", fh->m_max_cluster, 8 * fh->m_fd_rbsize, fh->m_cluster_cur);
939 cluster_cur = fh->m_cluster_cur;
940 if ( cluster_cur < 0 )
941 {
942 cluster_cur = 0;
943 }
944 else if (
945 (unsigned int)readpos_bsr_14 < (unsigned int)cluster_cur
946 || readpos_plus_nbytes_bsr_14 >= cluster_cur + 8 * fh->m_fd_rbsize )
947 {
948 int cluster_write_tmp2;
949 unsigned int readpos_band;
950
951 if ( lseek(fh->m_cache_file_fd, cluster_cur >> 3, 0) < 0 )
952 {
953 fh->m_cluster_cur = -1;
954 return -EIO;
955 }
956 cluster_write_tmp2 = (unsigned int)fh->m_max_cluster >= fh->m_cluster_cur + 8 * fh->m_fd_rbsize ?
957 fh->m_fd_rbsize :
958 ((unsigned int)fh->m_max_cluster - fh->m_cluster_cur + 7) >> 3;
959 if ( write(fh->m_cache_file_fd, fh->m_fd_rcvbuf, cluster_write_tmp2) != cluster_write_tmp2 )
960 {
961 fh->m_cluster_cur = -1;
962 return -EIO;
963 }
964 readpos_band = readpos_bsr_14 & ~0x7;
965 fh->m_cluster_cur = readpos_band;
966 readpos_band += (readpos_bsr_14 < 0) ? 7 : 0;
967 if ( (lseek(fh->m_cache_file_fd, readpos_band >> 3, 0) < 0) || (read(fh->m_cache_file_fd, fh->m_fd_rcvbuf, ( (unsigned int)fh->m_max_cluster < fh->m_cluster_cur + 8 * fh->m_fd_rbsize ) ? (((unsigned int)fh->m_max_cluster - fh->m_cluster_cur + 7) >> 3) : (fh->m_fd_rbsize)) < 0) )
968 {
969 fh->m_cluster_cur = -1;
970 return -EIO;
971 }
972 cluster_cur = fh->m_cluster_cur;
973 }
974 for ( i = readpos_bsr_14; i <= readpos_plus_nbytes_bsr_14; i += 1 )
975 {
976 if ( !(((int)fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] >> ((i - cluster_cur) & 7)) & 1) )
977 {
978 break;
979 }
980 }
981 return i <= readpos_plus_nbytes_bsr_14;
982}
983
984static int cdrom_internal_write_cache(const iop_file_t *f, unsigned int nbytes)
985{
986 int lseek_result;
988 unsigned int cur;
989 unsigned int rst;
990 int cluster_cur;
991 int write_ret;
992 unsigned int i;
993 int tray_open;
994 int Error;
995 sceCdRMode rmode;
996
997 g_cdvdman_iocache = 0;
998 if ( cdvdman_devready() < 0 )
999 {
1000 return -EBUSY;
1001 }
1002 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1003 if ( nbytes > fh->m_file_size - fh->m_read_pos )
1004 {
1005 nbytes = fh->m_file_size - fh->m_read_pos;
1006 }
1007 if ( !nbytes )
1008 {
1009 return 0;
1010 }
1011 VERBOSE_KPRINTF(1, "_cdvdfile_cache_read %d<->%d\n", fh->m_read_pos, fh->m_read_pos + nbytes);
1012 cur = ((fh->m_read_pos + nbytes) >> 14) - (!((fh->m_read_pos + nbytes) & 0x3FFF));
1013 rst = fh->m_read_pos >> 14;
1014 cluster_cur = (fh->m_cluster_cur >= 0) ? fh->m_cluster_cur : 0;
1015 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1016 write_ret = 0;
1017 VERBOSE_KPRINTF(1, "cache_fill rst:%d<->%d cur:%d cnt:%d\n", rst, cur, fh->m_read_pos, nbytes);
1018 for ( i = rst; i <= cur; i += 1 )
1019 {
1020 VERBOSE_KPRINTF(
1021 1,
1022 "FIO Usr addr LSN:%d SEC:%d ADDR:%08x cpos= %d\n",
1023 fh->m_file_lsn + 8 * i,
1024 8,
1025 g_cdvdman_temp_buffer_ptr,
1026 (i * 0x4000) + fh->m_sector_count_total);
1027 if ( !(((int)fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] >> ((i - cluster_cur) & 7)) & 1) )
1028 {
1029 tray_open = 0;
1030 while ( !sceCdRE(fh->m_file_lsn + 8 * i, 8u, g_cdvdman_temp_buffer_ptr, &rmode) )
1031 {
1032 if ( (sceCdStatus() & SCECdStatShellOpen) )
1033 {
1034 g_cdvdman_iocache = 0;
1035 tray_open = 1;
1036 break;
1037 }
1038 DelayThread(10000);
1039 }
1040 sceCdSync(0);
1041 Error = sceCdGetError();
1042 if ( Error || tray_open )
1043 {
1044 VERBOSE_KPRINTF(0, "Read Error= 0x%02x\n", Error);
1045 return -ECOMM;
1046 }
1047 lseek_result = lseek(fh->m_cache_file_fd, (i * 0x4000) + fh->m_sector_count_total, 0);
1048 if ( lseek_result < 0 )
1049 {
1050 return lseek_result;
1051 }
1052 write_ret = write(fh->m_cache_file_fd, g_cdvdman_temp_buffer_ptr, 0x4000);
1053 if ( write_ret != 0x4000 )
1054 {
1055 VERBOSE_KPRINTF(1, "write: ret:%d\n", write_ret);
1056 if ( write_ret >= 0 )
1057 {
1058 return -EIO;
1059 }
1060 break;
1061 }
1062 fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] |= 1 << ((i - cluster_cur) & 7);
1063 }
1064 }
1065 return write_ret;
1066}
1067
1068static int cdvdfile_cache_read(const iop_file_t *f, void *buf, int nbyte)
1069{
1070 int nbyte_tmp;
1071 int fd_result;
1072 cdvdman_fhinfo_t *fh;
1073
1074 if ( nbyte < 0 )
1075 {
1076 return -EINVAL;
1077 }
1078 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1079 nbyte_tmp =
1080 ((unsigned int)nbyte > fh->m_file_size - fh->m_read_pos) ? fh->m_file_size - fh->m_read_pos : (unsigned int)nbyte;
1081 VERBOSE_KPRINTF(1, "_cdvdfile_cache_read %d<->%d\n", fh->m_read_pos, fh->m_read_pos + nbyte_tmp);
1082 fd_result = 0;
1083 if ( nbyte_tmp > 0 )
1084 {
1085 fd_result = lseek(fh->m_cache_file_fd, fh->m_read_pos + fh->m_sector_count_total, 0);
1086 if ( fd_result >= 0 )
1087 {
1088 fd_result = read(fh->m_cache_file_fd, buf, nbyte_tmp);
1089 fh->m_read_pos += (fd_result >= 0) ? fd_result : 0;
1090 }
1091 }
1092 return fd_result;
1093}
1094
1095static int cdvdfile_cache_fill_read(const iop_file_t *f, void *buf, int nbytes)
1096{
1097 int op_result;
1098
1099 op_result = cdvdman_devready();
1100 if ( op_result >= 0 )
1101 {
1102 op_result = cdrom_internal_write_cache(f, nbytes);
1103 }
1104 else
1105 {
1106 g_cdvdman_iocache = 0;
1107 }
1108 if ( op_result >= 0 )
1109 {
1110 op_result = cdvdfile_cache_read(f, buf, nbytes);
1111 }
1112 return op_result;
1113}
1114
1115static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4)
1116{
1117 int fds1;
1118 unsigned int i;
1119 int emptyfdfound;
1120 int streamfdfound;
1121 cdvdman_fhinfo_t *fh;
1122 int devready_tmp;
1123 char filename[128];
1124 sceCdlFILE fp;
1125 u32 efbits;
1126
1127 (void)arg4;
1128 devready_tmp = 0;
1129 fds1 = 0;
1130 VERBOSE_PRINTF(1, "fileIO OPEN name= %s mode= 0x%08x layer %d\n", name, mode, f->unit);
1131 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
1132 emptyfdfound = 0;
1133 streamfdfound = 0;
1134 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1135 {
1136 if ( !g_cdvdman_fhinfo[i].m_fd_flags && !emptyfdfound )
1137 {
1138 fds1 = i;
1139 emptyfdfound = 1;
1140 }
1141 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 8) )
1142 {
1143 streamfdfound = 1;
1144 }
1145 }
1146 if ( !emptyfdfound || streamfdfound )
1147 {
1148 PRINTF("open fail name %s\n", name);
1149 SetEventFlag(g_fio_fsv_evid, 1);
1150 return -EMFILE;
1151 }
1152 f->privdata = (void *)fds1;
1153 fh = &g_cdvdman_fhinfo[fds1];
1154 strncpy(filename, name, sizeof(filename));
1155 cdvdman_cdfname(filename);
1156 g_cdvdman_srchspd = (!(mode & 0x40000000) && !cdvdman_l0check(f->unit)) ?
1157 ((g_cdvdman_spinnom == -1) ? (u16)mode : g_cdvdman_spinnom != SCECdSpinStm) :
1158 0;
1159 if ( (unsigned int)(f->unit) >= 2u )
1160 {
1161 devready_tmp = -ENOENT;
1162 }
1163 else
1164 {
1165 if ( !strncmp(name, "sce_cdvd_lsn", 12) )
1166 {
1167 strncpy(filename, name, sizeof(filename));
1168 // Unofficial: Avoid out of bounds access
1169 for ( i = 12; i < (sizeof(filename) - 5) && filename[i] && filename[i] != '_'; i += 1 )
1170 ;
1171 if ( !filename[i] || i >= (sizeof(filename) - 5) )
1172 {
1173 devready_tmp = -ENOENT;
1174 }
1175 else
1176 {
1177 fp.size = strtol(&filename[i + 5], 0, 10);
1178 filename[i] = 0;
1179 fp.lsn = strtol(&filename[12], 0, 10);
1180 if ( f->unit )
1181 {
1182 if ( cdvdman_devready() < 0 || !DvdDual_infochk() )
1183 {
1184 devready_tmp = -ENOENT;
1185 }
1186 else
1187 {
1188 fp.lsn += g_cdvdman_istruct.m_layer_1_lsn;
1189 }
1190 }
1191 }
1192 }
1193 else
1194 {
1195 devready_tmp = cdvdman_devready();
1196 if ( devready_tmp < 0 )
1197 {
1198 SetEventFlag(g_fio_fsv_evid, 1);
1199 return devready_tmp;
1200 }
1201 if ( !sceCdLayerSearchFile(&fp, filename, f->unit) )
1202 {
1203 devready_tmp = -ENOENT;
1204 }
1205 }
1206 }
1207 if ( devready_tmp < 0 )
1208 {
1209 PRINTF("open fail name %s\n", filename);
1210 SetEventFlag(g_fio_fsv_evid, 1);
1211 return devready_tmp;
1212 }
1213 fh->m_fd_flags = 1;
1214 g_cdvdman_srchspd = 0;
1215 if ( (mode & 0x40000000) )
1216 {
1217 sceCdRMode rmode;
1218 memset(&rmode, 0, sizeof(rmode));
1219 rmode.datapattern = SCECdSecS2048;
1220 rmode.spindlctrl = SCECdSpinStm;
1221 rmode.trycount = (g_cdvdman_trycnt != -1) ? g_cdvdman_trycnt : 0;
1222 // The following call to sceCdStStart was inlined
1223 if ( !sceCdStStart(fp.lsn, &rmode) )
1224 {
1225 fh->m_fd_flags = 0;
1226 SetEventFlag(g_fio_fsv_evid, 1);
1227 return -ENOENT;
1228 }
1229 g_cdvdman_strmerr = 0;
1230 fh->m_fd_flags |= 8;
1231 }
1232 fh->m_file_lsn = fp.lsn;
1233 fh->m_read_pos = 0;
1234 fh->m_filemode = mode & ~0x40000000;
1235 fh->m_file_size = fp.size;
1236 fh->m_fd_layer = f->unit;
1237 if ( (mode & 0x50000000) == 0x10000000 )
1238 {
1239 devready_tmp = -ENODEV;
1240 if ( g_cache_path_fd != -1 )
1241 {
1242 devready_tmp = cdvd_odcinit(fh, 1, (int)f->privdata);
1243 if ( devready_tmp >= 0 )
1244 {
1245 fh->m_fd_flags |= 4;
1246 }
1247 }
1248 }
1249 if ( devready_tmp < 0 )
1250 {
1251 fh->m_fd_flags = 0;
1252 fh->m_fd_layer = 0;
1253 fh->m_filemode = 0;
1254 fh->m_read_pos = 0;
1255 fh->m_file_size = 0;
1256 fh->m_file_lsn = 0;
1257 SetEventFlag(g_fio_fsv_evid, 1);
1258 return devready_tmp;
1259 }
1260 f->mode = O_RDONLY;
1261 SetEventFlag(g_fio_fsv_evid, 1);
1262 return 0;
1263}
1264
1265static int cdrom_close(iop_file_t *f)
1266{
1267 cdvdman_fhinfo_t *fh;
1268 u32 efbits;
1269
1270 VERBOSE_PRINTF(1, "fileIO CLOSE\n");
1271 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
1272 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1273 if ( (fh->m_fd_flags & 8) )
1274 {
1275 g_cdvdman_strmerr = 0;
1276 // The following call to sceCdStStop was inlined
1277 if ( !sceCdStStop() )
1278 {
1279 SetEventFlag(g_fio_fsv_evid, 1);
1280 return -EIO;
1281 }
1282 }
1283 if ( ((fh->m_fd_flags & 0xC) == 4 && cdvd_odcinit(fh, 0, (int)f->privdata) < 0) )
1284 {
1285 SetEventFlag(g_fio_fsv_evid, 1);
1286 return -EIO;
1287 }
1288 fh->m_file_lsn = 0;
1289 fh->m_file_size = 0;
1290 fh->m_read_pos = 0;
1291 fh->m_fd_flags = 0;
1292 fh->m_fd_layer = 0;
1293 fh->m_filemode = 1;
1294 f->mode = 0;
1295 SetEventFlag(g_fio_fsv_evid, 1);
1296 return 0;
1297}
1298
1299static int cdrom_internal_read(const iop_file_t *f, char *addr, int nbytes)
1300{
1301 unsigned int sectors;
1302 int op_result;
1303 int nbytes_segment;
1304 int nbytes_div_2048;
1305 unsigned int sec;
1306 int read_error;
1307 unsigned int sectors_count;
1308 int Error;
1309 sceCdRMode rmode;
1310 int i;
1311 unsigned int filesize_bsr_11;
1312 cdvdman_fhinfo_t *fh;
1313 void *buf;
1314
1315 sectors = 1;
1316 VERBOSE_PRINTF(1, "cdvd fileIO read start\n");
1317 op_result = cdvdman_devready();
1318 if ( op_result < 0 )
1319 {
1320 g_cdvdman_iocache = 0;
1321 return op_result;
1322 }
1323 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1324 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1325 if ( nbytes < 0 )
1326 {
1327 return -EINVAL;
1328 }
1329 if ( (unsigned int)nbytes > fh->m_file_size - fh->m_read_pos )
1330 {
1331 nbytes = fh->m_file_size - fh->m_read_pos;
1332 }
1333 filesize_bsr_11 = (fh->m_file_size >> 11) + (!!((fh->m_file_size & 0x7FF))) + fh->m_file_lsn;
1334 VERBOSE_PRINTF(
1335 1, "fds= %d read file_lbn= %d offset= %d\n", (int)(uiptr)f->privdata, (int)fh->m_file_lsn, (int)fh->m_read_pos);
1336 buf = 0;
1337 for ( i = 0; i < nbytes; i += nbytes_segment )
1338 {
1339 unsigned int lbn;
1340 int pos_extra;
1341 int lbn_tmp;
1342 int pos_sub_2048;
1343 int nbytes_cur;
1344
1345 nbytes_cur = nbytes - i;
1346 if ( g_cdvdman_spinctl != -1 )
1347 {
1348 rmode.spindlctrl = g_cdvdman_spinctl;
1349 switch ( g_cdvdman_spinctl )
1350 {
1351 case SCECdSpinStm:
1352 fh->m_filemode = 0;
1353 break;
1354 case SCECdSpinNom:
1355 fh->m_filemode = 1;
1356 break;
1357 case SCECdSpinX1:
1358 fh->m_filemode = 2;
1359 break;
1360 case SCECdSpinX2:
1361 fh->m_filemode = 3;
1362 break;
1363 case SCECdSpinX4:
1364 fh->m_filemode = 4;
1365 break;
1366 case SCECdSpinX12:
1367 fh->m_filemode = 5;
1368 break;
1369 default:
1370 fh->m_filemode = 1;
1371 break;
1372 }
1373 }
1374 pos_sub_2048 = 0;
1375 lbn = fh->m_file_lsn + ((fh->m_read_pos + i) >> 11);
1376 lbn_tmp = lbn;
1377 pos_extra = (fh->m_read_pos + i) & 0x7FF;
1378 if ( nbytes_cur <= 0x4000 )
1379 {
1380 nbytes_segment = nbytes_cur;
1381 nbytes_div_2048 = (nbytes_cur / 0x800) + (!!((nbytes_cur & 0x7FF)));
1382 sectors = nbytes_div_2048 + (!!pos_extra);
1383 }
1384 else
1385 {
1386 nbytes_segment = 0x4000;
1387 if ( buf && ((fh->m_read_pos + i) & 0x7FF) && g_cdvdman_iocache )
1388 {
1389 lbn += 1;
1390 pos_sub_2048 = 0x800 - pos_extra;
1391 optimized_memcpy(
1392 &addr[i], &((const char *)g_cdvdman_temp_buffer_ptr)[0x800 * (sectors - 1) + pos_extra], 0x800 - pos_extra);
1393 g_cdvdman_iocache = 0;
1394 sectors = 8;
1395 }
1396 else
1397 {
1398 sectors = 8 + (!!(((fh->m_read_pos + i) & 0x7FF)));
1399 }
1400 }
1401 buf = g_cdvdman_temp_buffer_ptr;
1402 if ( (unsigned int)(sectors) > filesize_bsr_11 - lbn )
1403 {
1404 sectors = filesize_bsr_11 - lbn;
1405 }
1406 VERBOSE_PRINTF(1, "sce_Read LBN= %d sectors= %d\n", (int)lbn, (int)sectors);
1407 if (
1408 g_cdvdman_iocache && (lbn >= g_cdvdman_lcn_offset)
1409 && (g_cdvdman_lcn_offset + g_cdvdman_numbytes_offset >= lbn + sectors) )
1410 {
1411 optimized_memcpy(&addr[i], &((char *)buf)[0x800 * (lbn - g_cdvdman_lcn_offset) + pos_extra], nbytes_segment);
1412 }
1413 else if ( ((uiptr)(addr + i) & 3) || pos_extra || (nbytes_segment != 0x4000) )
1414 {
1415 sec = (sectors >= 8) ? sectors : 8;
1416 if ( sec > filesize_bsr_11 - lbn )
1417 {
1418 sec = filesize_bsr_11 - lbn;
1419 }
1420 VERBOSE_PRINTF(1, "FIO Cache LSN:%d SEC:%d ADDR:%08x\n", (int)lbn, (int)sec, (unsigned int)(uiptr)buf);
1421 sectors_count = (sec >= 9) ? (sec - 8) : 0;
1422 if ( sectors_count )
1423 {
1424 while ( !sceCdRE(lbn, sectors_count, buf, &rmode) )
1425 {
1426 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1427 if ( (sceCdStatus() & SCECdStatShellOpen) )
1428 {
1429 g_cdvdman_iocache = 0;
1430 g_cdvdman_spinctl = -1;
1431 return -EIO;
1432 }
1433 DelayThread(10000);
1434 }
1435 sceCdSync(0);
1436 Error = sceCdGetError();
1437 if ( Error )
1438 {
1439 PRINTF("Read Error= 0x%02x\n", Error);
1440 g_cdvdman_iocache = 0;
1441 break;
1442 }
1443 }
1444 while ( !sceCdRE(lbn + sectors_count, sec - sectors_count, (char *)buf + 0x800 * sectors_count, &rmode) )
1445 {
1446 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1447 if ( (sceCdStatus() & SCECdStatShellOpen) )
1448 {
1449 g_cdvdman_iocache = 0;
1450 g_cdvdman_spinctl = -1;
1451 return -EIO;
1452 }
1453 DelayThread(10000);
1454 }
1455 sceCdSync(0);
1456 Error = sceCdGetError();
1457 if ( Error )
1458 {
1459 PRINTF("Read Error= 0x%02x\n", Error);
1460 g_cdvdman_iocache = 0;
1461 break;
1462 }
1463 g_cdvdman_lcn_offset = lbn_tmp;
1464 g_cdvdman_numbytes_offset = sec;
1465 g_cdvdman_iocache = 1;
1466 optimized_memcpy(
1467 &addr[pos_sub_2048 + i],
1468 &((const char *)g_cdvdman_temp_buffer_ptr)[!pos_sub_2048 ? pos_extra : 0],
1469 nbytes_segment - pos_sub_2048);
1470 }
1471 else
1472 {
1473 VERBOSE_PRINTF(
1474 1, "FIO Usr addr LSN:%d SEC:%d ADDR:%08x\n", (int)lbn, (int)sectors, (unsigned int)(uiptr)(addr + i));
1475 while ( !sceCdRE(lbn, sectors, addr + i, &rmode) )
1476 {
1477 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1478 if ( (sceCdStatus() & SCECdStatShellOpen) )
1479 {
1480 g_cdvdman_iocache = 0;
1481 g_cdvdman_spinctl = -1;
1482 return -EIO;
1483 }
1484 DelayThread(10000);
1485 }
1486 sceCdSync(0);
1487 read_error = sceCdGetError();
1488 g_cdvdman_iocache = 0;
1489 if ( read_error )
1490 {
1491 PRINTF("Read Error= 0x%02x\n", read_error);
1492 break;
1493 }
1494 }
1495 if ( nbytes_segment <= 0 )
1496 {
1497 g_cdvdman_spinctl = -1;
1498 return nbytes_segment;
1499 }
1500 }
1501 fh->m_read_pos += i;
1502 VERBOSE_PRINTF(1, "fileIO read ended\n");
1503 g_cdvdman_spinctl = -1;
1504 return i;
1505}
1506
1507static int cdrom_stream_read(const iop_file_t *f, char *bbuf, int nbytes)
1508{
1509 cdvdman_fhinfo_t *fh;
1510 sceCdRMode rmode;
1511 int buf;
1512
1513 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1514 g_cdvdman_strmerr = 0;
1515 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1516 rmode.spindlctrl = SCECdSpinStm;
1517 rmode.trycount = 0;
1518 // The following sceCdStRead call was inlined
1519 buf = sceCdStRead(nbytes >> 11, (u32 *)bbuf, STMNBLK, (u32 *)&g_cdvdman_strmerr);
1520 fh->m_read_pos += buf << 11;
1521 return buf << 11;
1522}
1523
1524static int cdrom_read(iop_file_t *f, void *buf, int nbytes)
1525{
1526 cdvdman_fhinfo_t *fh;
1527 int rc;
1528 u32 efbits;
1529
1530 if ( nbytes < 0 )
1531 {
1532 return -EINVAL;
1533 }
1534 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
1535 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1536 if ( cdvdman_mediactl(2) )
1537 {
1538 g_cdvdman_iocache = 0;
1539 cdvdman_invcaches();
1540 }
1541 if ( (fh->m_fd_flags & 8) )
1542 {
1543 rc = cdrom_stream_read(f, (char *)buf, nbytes);
1544 }
1545 else
1546 {
1547 if ( !(fh->m_fd_flags & 4) )
1548 {
1549 rc = cdrom_internal_read(f, (char *)buf, nbytes);
1550 }
1551 else
1552 {
1553 rc = cdrom_internal_cache_read(f, nbytes);
1554 if ( rc )
1555 {
1556 if ( rc != -EBUSY )
1557 {
1558 if ( rc != 1 )
1559 {
1560 fh->m_fd_flags &= ~4;
1561 rc = -EIO;
1562 cdvd_odcinit(fh, 0, (int)f->privdata);
1563 }
1564 else
1565 {
1566 rc = cdvdfile_cache_fill_read(f, buf, nbytes);
1567 VERBOSE_KPRINTF(1, "called _cdvdfile_cache_fill_read %d\n", rc);
1568 }
1569 }
1570 }
1571 else
1572 {
1573 rc = cdvdfile_cache_read(f, buf, nbytes);
1574 VERBOSE_KPRINTF(1, "called _cdvdfile_cache_read %d\n", rc);
1575 }
1576 if ( rc == -EBUSY || rc == -ECOMM )
1577 {
1578 cdvdman_cache_invalidate(fh, (int)f->privdata);
1579 KPRINTF("_cdvdfile_cache Read_err OR Drive_not_ready\n", rc);
1580 }
1581 if ( rc < 0 )
1582 {
1583 rc = cdrom_internal_read(f, (char *)buf, nbytes);
1584 }
1585 }
1586 }
1587 SetEventFlag(g_fio_fsv_evid, 1);
1588 return rc;
1589}
1590
1591static int cdrom_ioctl(iop_file_t *f, int arg, void *param)
1592{
1593 (void)f;
1594
1595 switch ( arg )
1596 {
1597 case 0x10000:
1598 g_cdvdman_spinnom = -1;
1599 sceCdSpinCtrlIOP((u32)param);
1600 return 0;
1601 default:
1602 return -EIO;
1603 }
1604}
1605
1606static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen)
1607{
1608 const cdvdman_fhinfo_t *fh;
1609 int retval;
1610 u32 efbits;
1611
1612 (void)argp;
1613 (void)arglen;
1614 (void)bufp;
1615 (void)buflen;
1616
1617 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
1618 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1619 retval = -EIO;
1620 if ( (fh->m_fd_flags & 8) )
1621 {
1622 switch ( request )
1623 {
1624 case CIOCSTREAMPAUSE:
1625 // The following call to sceCdStPause was inlined
1626 if ( sceCdStPause() )
1627 {
1628 retval = 0;
1629 }
1630 break;
1631 case CIOCSTREAMRESUME:
1632 // The following call to sceCdStResume was inlined
1633 if ( sceCdStResume() )
1634 {
1635 retval = 0;
1636 }
1637 break;
1638 case CIOCSTREAMSTAT:
1639 // The following call to sceCdStStat was inlined
1640 // Unofficial: return 0 instead of negative value
1641 retval = sceCdStStat();
1642 break;
1643 default:
1644 break;
1645 }
1646 }
1647 SetEventFlag(g_fio_fsv_evid, 1);
1648 return retval;
1649}
1650
1651static int
1652cdrom_devctl(iop_file_t *f, const char *name, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen)
1653{
1654 unsigned int i;
1655 int retval2;
1656 char *sc_tmp_2;
1657 unsigned int sc_tmp_3;
1658 u32 efbits;
1659 int on_dual_tmp;
1660 int scres_unused;
1661
1662 (void)f;
1663 (void)name;
1664 (void)buflen;
1665
1666 retval2 = 0;
1667 if ( cmd != CDIOC_BREAK )
1668 {
1669 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
1670 }
1671 switch ( cmd )
1672 {
1673 case CDIOC_READCLOCK:
1674 for ( i = 0; i < 3 && !retval2; i += 1 )
1675 {
1676 WaitEventFlag(g_scmd_evid, 1, WEF_AND, &efbits);
1677 retval2 = sceCdReadClock((sceCdCLOCK *)bufp);
1678 }
1679 retval2 = (retval2 != 1) ? -EIO : 0;
1680 break;
1681#ifdef CDVD_VARIANT_DNAS
1682 case 0x431D:
1683 for ( i = 0; i < 3 && !retval2; i += 1 )
1684 {
1685 WaitEventFlag(g_scmd_evid, 1, WEF_AND, &efbits);
1686 retval2 = sceCdReadGUID((u64 *)bufp);
1687 }
1688 retval2 = (retval2 != 1) ? -EIO : 0;
1689 break;
1690 case 0x431E:
1691 retval2 = (sceCdReadDiskID((unsigned int *)bufp) != 1) ? -EIO : 0;
1692 break;
1693#endif
1694 case CDIOC_GETDISKTYP:
1695 *(u32 *)bufp = sceCdGetDiskType();
1696 break;
1697 case CDIOC_GETERROR:
1698 *(u32 *)bufp = g_cdvdman_strmerr ? g_cdvdman_strmerr : sceCdGetError();
1699 break;
1700 case CDIOC_TRAYREQ:
1701 retval2 = (sceCdTrayReq(*(u32 *)argp, (u32 *)bufp) != 1) ? -EIO : 0;
1702 break;
1703 case CDIOC_STATUS:
1704 *(u32 *)bufp = sceCdStatus();
1705 break;
1706 case CDIOC_POWEROFF:
1707 for ( i = 0; i < 3 && !retval2; i += 1 )
1708 {
1709 WaitEventFlag(g_scmd_evid, 1, WEF_AND, &efbits);
1710 retval2 = sceCdPowerOff((u32 *)bufp);
1711 }
1712 retval2 = (retval2 != 1) ? -EIO : 0;
1713 break;
1714 case CDIOC_MMODE:
1715 sceCdMmode(*(u32 *)argp);
1716 break;
1717 case CDIOC_DISKRDY:
1718 *(u32 *)bufp = sceCdDiskReady(*(u32 *)argp);
1719 break;
1720#ifdef CDVD_VARIANT_DNAS
1721 case 0x4326:
1722 for ( i = 0; i < 3 && !retval2; i += 1 )
1723 {
1724 WaitEventFlag(g_scmd_evid, 1, WEF_AND, &efbits);
1725 retval2 = sceCdReadModelID((unsigned int *)bufp);
1726 }
1727 retval2 = (retval2 != 1) ? -EIO : 0;
1728 break;
1729#endif
1730 case CDIOC_STREAMINIT:
1731 // The following call to sceCdStInit was inlined
1732 retval2 = (!sceCdStInit(*(u32 *)argp, *((u32 *)argp + 1), (void *)*((u32 *)argp + 2))) ? -EIO : 0;
1733 break;
1734 case CDIOC_BREAK:
1735 retval2 = (!sceCdBreak()) ? -EIO : 0;
1736 sceCdSync(4);
1737 break;
1738 case CDIOC_SPINNOM:
1739 g_cdvdman_spinnom = SCECdSpinNom;
1740 break;
1741 case CDIOC_SPINSTM:
1742 g_cdvdman_spinnom = SCECdSpinStm;
1743 break;
1744 case CDIOC_TRYCNT:
1745 g_cdvdman_trycnt = *(u8 *)argp;
1746 break;
1747 case 0x4383:
1748 retval2 = (sceCdSeek(*(u32 *)argp) != 1) ? -EIO : 0;
1749 sceCdSync(6);
1750 break;
1751 case CDIOC_STANDBY:
1752 retval2 = (sceCdStandby() != 1) ? -EIO : 0;
1753 sceCdSync(4);
1754 break;
1755 case CDIOC_STOP:
1756 retval2 = (sceCdStop() != 1) ? -EIO : 0;
1757 sceCdSync(4);
1758 break;
1759 case CDIOC_PAUSE:
1760 retval2 = (sceCdPause() != 1) ? -EIO : 0;
1761 sceCdSync(6);
1762 break;
1763 case CDIOC_GETTOC:
1764 switch ( sceCdGetDiskType() )
1765 {
1766 case SCECdPSCD:
1767 case SCECdPSCDDA:
1768 case SCECdPS2CD:
1769 case SCECdPS2CDDA:
1770 retval2 = (sceCdGetToc((u8 *)bufp) != 1) ? -EIO : 0;
1771 break;
1772 default:
1773 break;
1774 }
1775 break;
1776 case CDIOC_SETTIMEOUT:
1777 retval2 = (sceCdSetTimeout(1, *(u32 *)argp) != 1) ? -EIO : 0;
1778 break;
1779 case CDIOC_READDVDDUALINFO:
1780 retval2 = (!sceCdReadDvdDualInfo(&on_dual_tmp, (unsigned int *)bufp)) ? -EIO : 0;
1781 break;
1782 case CDIOC_INIT:
1783 sceCdInit(*(u32 *)argp);
1784 retval2 = 0;
1785 break;
1786 case 0x438C:
1787 g_cdvdman_spinnom = SCECdSpinX1;
1788 break;
1789 case 0x438D:
1790 g_cdvdman_spinnom = SCECdSpinX2;
1791 break;
1792 case 0x438E:
1793 g_cdvdman_spinnom = SCECdSpinX4;
1794 break;
1795 case 0x438F:
1796 g_cdvdman_spinnom = SCECdSpinX12;
1797 break;
1798 case 0x4390:
1799 g_cdvdman_spinnom = SCECdSpinMx;
1800 break;
1801 case 0x4391:
1802 *(u32 *)bufp = sceCdSC(0xFFFFFFF5, &scres_unused);
1803 break;
1804 case 0x4392:
1805 retval2 = (sceCdApplySCmd(*(u8 *)argp, (char *)argp + 4, arglen - 4, bufp) != 1) ? -EIO : 0;
1806 break;
1807 case CDIOC_FSCACHEINIT:
1808 retval2 = -EBUSY;
1809 if ( g_cache_path_fd != -1 )
1810 {
1811 break;
1812 }
1813 retval2 = -EINVAL;
1814 sc_tmp_2 = (char *)argp;
1815 for ( i = 0; i < arglen && sc_tmp_2[i] && sc_tmp_2[i] != ','; i += 1 )
1816 {
1817 g_cdvdman_cache_name[i] = sc_tmp_2[i];
1818 }
1819 sc_tmp_3 = i;
1820 if ( i <= arglen )
1821 {
1822 i += 1;
1823 for ( ; (i < arglen) && sc_tmp_2[i] && sc_tmp_2[i] != ','; i += 1 )
1824 {
1825 }
1826 }
1827 if ( i <= arglen )
1828 {
1829 sc_tmp_2[i] = 0;
1830 g_cdvdman_cache_sector_size_count = strtol((const char *)argp + sc_tmp_3, 0, 10);
1831 retval2 = path_tbl_init(strtol(&sc_tmp_2[i + 1], 0, 10), g_cdvdman_cache_name, 1);
1832 }
1833 break;
1834 case CDIOC_FSCACHEDELETE:
1835 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1836 {
1837 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 4) )
1838 {
1839 break;
1840 }
1841 }
1842 retval2 = (i == (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0]))) ? path_tbl_init(0, 0, 0) : -EBUSY;
1843 break;
1844 default:
1845 retval2 = -EIO;
1846 break;
1847 }
1848 if ( cmd != CDIOC_BREAK )
1849 {
1850 SetEventFlag(g_fio_fsv_evid, 1);
1851 }
1852 return retval2;
1853}
1854
1855static int cdrom_lseek(iop_file_t *f, int offset, int pos)
1856{
1857 int retval;
1858 cdvdman_fhinfo_t *fh;
1859 u32 efbits;
1860
1861 retval = -EPERM;
1862 VERBOSE_PRINTF(1, "fileIO SEEK\n");
1863 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
1864 fh = &g_cdvdman_fhinfo[(int)f->privdata];
1865 switch ( pos )
1866 {
1867 case 0:
1868 retval = offset;
1869 break;
1870 case 1:
1871 retval = fh->m_read_pos + offset;
1872 break;
1873 case 2:
1874 retval = fh->m_file_size - offset;
1875 break;
1876 default:
1877 break;
1878 }
1879 if ( retval > (int)(fh->m_file_size) )
1880 {
1881 retval = fh->m_file_size;
1882 }
1883 fh->m_read_pos = retval;
1884 if ( (fh->m_fd_flags & 8) )
1885 {
1886 // The following call to sceCdStSeekF was inlined
1887 if ( !sceCdStSeekF(fh->m_file_lsn + retval / 0x800) )
1888 {
1889 retval = -EIO;
1890 }
1891 }
1892 SetEventFlag(g_fio_fsv_evid, 1);
1893 return retval;
1894}
1895
1896static int cdrom_nulldev()
1897{
1898 PRINTF("nulldev0 call\n");
1899 return -EIO;
1900}
1901
1902static s64 cdrom_nulldev64()
1903{
1904 PRINTF("nulldev0 call\n");
1905 return -EIO;
1906}
1907
1908static int sync_timeout_alarm_cb(const iop_sys_clock_t *sys_clock)
1909{
1910 KPRINTF("Cdvd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
1911 return !sceCdBreak();
1912}
1913
1914int sceCdSetTimeout(int param, int timeout)
1915{
1916 if ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
1917 {
1918 return 0;
1919 }
1920 switch ( param )
1921 {
1922 case 1:
1923 g_cdvdman_sync_timeout = timeout;
1924 return 1;
1925 case 2:
1926 g_cdvdman_stream_timeout = timeout;
1927 return 1;
1928 default:
1929 return 0;
1930 }
1931}
1932
1933int sceCdSync(int mode)
1934{
1935 iop_sys_clock_t sysclk;
1936 iop_event_info_t efinfo;
1937 u32 efbits;
1938
1939 VERBOSE_KPRINTF(1, "sceCdSync: Call mode %d Com %x\n", mode, (u8)g_cdvdman_istruct.m_cdvdman_command);
1940 switch ( mode )
1941 {
1942 case 0:
1943 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
1944 {
1945 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
1946 }
1947 break;
1948 case 1:
1949 return !!(!sceCdCheckCmd() || (g_cdvdman_istruct.m_read2_flag));
1950 case 3:
1951 sysclk.hi = 0;
1952 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
1953 vSetAlarm(&sysclk, (unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
1954 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
1955 {
1956 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
1957 }
1958 vCancelAlarm((unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
1959 break;
1960 case 4:
1961 sysclk.hi = 0;
1962 sysclk.lo = 0x41EB0000;
1963 vSetAlarm(&sysclk, (unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
1964 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
1965 {
1966 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
1967 }
1968 vCancelAlarm((unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
1969 break;
1970 case 5:
1971 while ( !sceCdCheckCmd() )
1972 {
1973 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
1974 }
1975 break;
1976 case 6:
1977 sysclk.hi = 0;
1978 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
1979 vSetAlarm(&sysclk, (unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
1980 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
1981 {
1982 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
1983 }
1984 vCancelAlarm((unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
1985 break;
1986 case 16:
1987 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
1988 || g_cdvdman_istruct.m_stream_flag )
1989 {
1990 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
1991 if ( g_cdvdman_ee_rpc_fno )
1992 {
1993 DelayThread(8000);
1994 }
1995 }
1996 break;
1997 case 17:
1998 return !!(
1999 !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2000 || (g_cdvdman_istruct.m_stream_flag));
2001 case 32:
2002 WaitEventFlag(g_cdvdman_intr_efid, 0x21, WEF_OR, &efbits);
2003 ReferEventFlagStatus(g_cdvdman_intr_efid, &efinfo);
2004 if ( !(efinfo.currBits & 0x20) )
2005 {
2006 if ( g_cdvdman_istruct.m_last_error )
2007 {
2008 SetEventFlag(g_cdvdman_intr_efid, 0x20);
2009 }
2010 else
2011 {
2012 WaitEventFlag(g_cdvdman_intr_efid, 0x20, WEF_AND, &efbits);
2013 }
2014 }
2015 break;
2016 default:
2017 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2018 {
2019 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
2020 }
2021 break;
2022 }
2023 VERBOSE_KPRINTF(
2024 1,
2025 "sceCdSync: Command= %d Error= %d\n",
2026 (u8)g_cdvdman_istruct.m_cdvdman_command,
2027 (u8)g_cdvdman_istruct.m_last_error);
2028 return 0;
2029}
2030
2031int sceCdSpinCtrlIOP(u32 speed)
2032{
2033 VERBOSE_KPRINTF(1, "sceCdSpinCtrlIOP speed= %d\n", speed);
2034 g_cdvdman_spinctl = speed;
2035 return 1;
2036}
2037
2038int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
2039{
2040 unsigned int i;
2041 int search_res;
2042 u32 efbits;
2043
2044 if ( PollEventFlag(g_sfile_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
2045 {
2046 return 0;
2047 }
2048 for ( i = 0; i < ((sizeof(g_cdvdman_sfname) / sizeof(g_cdvdman_sfname[0])) - 1) && path[i]; i += 1 )
2049 {
2050 g_cdvdman_sfname[i] = path[i];
2051 }
2052 g_cdvdman_sfname[i] = 0;
2053 g_cdvdman_srchspd = 1;
2054 search_res = CdSearchFileInner((cdvdman_filetbl_entry_t *)fp, g_cdvdman_sfname, layer);
2055 vSetEventFlag(g_sfile_evid, 1);
2056 return search_res;
2057}
2058
2059int sceCdSearchFile(sceCdlFILE *file, const char *name)
2060{
2061 return sceCdLayerSearchFile(file, name, 0);
2062}
2063
2064int sceCdGetToc(u8 *toc)
2065{
2066 return cdvdman_gettoc(toc);
2067}
2068
2069int sceCdDiskReady(int mode)
2070{
2071 u32 efbits;
2072 USE_DEV5_MMIO_HWPORT();
2073
2074 efbits = 0;
2075 VERBOSE_KPRINTF(1, "DISK READY call from iop\n");
2076 switch ( mode )
2077 {
2078 case 0:
2079 VERBOSE_KPRINTF(1, "Wait Drive Ready %x\n", dev5_mmio_hwport->m_dev5_reg_005);
2080 while ( 1 )
2081 {
2082 if ( !g_cdvdman_istruct.m_read2_flag )
2083 {
2084 return 2;
2085 }
2086 // The following call to sceCdGetDiskType was inlined
2087 switch ( sceCdGetDiskType() )
2088 {
2089 case SCECdDETCT:
2090 case SCECdDETCTCD:
2091 case SCECdDETCTDVDS:
2092 case SCECdDETCTDVDD:
2093 break;
2094 default:
2095 return 2;
2096 }
2097 while ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) != 0x40 )
2098 {
2099 vDelayThread(2000);
2100 WaitEventFlag(g_cdvdman_intr_efid, 1, WEF_AND, &efbits);
2101 }
2102 }
2103 break;
2104 case 8:
2105 return (u8)dev5_mmio_hwport->m_dev5_reg_005;
2106 case 1:
2107 default:
2108 if ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag )
2109 {
2110 return 2;
2111 }
2112 VERBOSE_KPRINTF(1, "Drive Not Ready\n");
2113 return 6;
2114 }
2115}
2116
2117int sceCdGetDiskType(void)
2118{
2119 USE_DEV5_MMIO_HWPORT();
2120
2121 return (u8)dev5_mmio_hwport->m_dev5_reg_00F;
2122}
2123
2124int sceCdStatus(void)
2125{
2126 int reg_00A_tmp;
2127 u32 status_tmp;
2128 USE_DEV5_MMIO_HWPORT();
2129
2130 reg_00A_tmp = dev5_mmio_hwport->m_dev5_reg_00A;
2131 // The following call to sceCdGetDiskType was inlined
2132 if ( sceCdGetDiskType() == SCECdNODISC )
2133 {
2134 u8 rdata_tmp;
2135
2136 if ( !g_cdvdman_istruct.m_tray_is_open && cdvdman_scmd_sender_03_48(&rdata_tmp, &status_tmp) == 1 && !status_tmp )
2137 {
2138 reg_00A_tmp &= ~SCECdStatShellOpen;
2139 if ( (rdata_tmp & 8) )
2140 {
2141 reg_00A_tmp |= SCECdStatShellOpen;
2142 }
2143 }
2144 if ( (reg_00A_tmp & 0x1E) )
2145 {
2146 reg_00A_tmp = SCECdStatStop;
2147 }
2148 }
2149 if ( g_cdvdman_istruct.m_use_toc )
2150 {
2151 reg_00A_tmp &= ~SCECdStatShellOpen;
2152 }
2153 if ( g_cdvdman_istruct.m_power_flag )
2154 {
2155 return -1;
2156 }
2157 return reg_00A_tmp;
2158}
2159
2161{
2162 p->sector = 16 * ((i + 150) % 75 / 10) + (i + 150) % 75 % 10;
2163 p->second = 16 * ((i + 150) / 75 % 60 / 10) + (i + 150) / 75 % 60 % 10;
2164 p->minute = 16 * ((i + 150) / 75 / 60 / 10) + (i + 150) / 75 / 60 % 10;
2165 return p;
2166}
2167
2169{
2170 return 75 * (60 * (10 * (p->minute >> 4) + (p->minute & 0xF)) + 10 * (p->second >> 4) + (p->second & 0xF))
2171 + 10 * (p->sector >> 4) + (p->sector & 0xF) - 150;
2172}
2173
2174#ifdef CDVD_VARIANT_DNAS
2175static int read_id_from_rom(int mode, int *buf)
2176{
2177 int chksumint;
2178 unsigned int i;
2179 unsigned int j;
2180 int idinfo[0x20];
2181 int chksumstk;
2182
2183 chksumint = 0;
2184 chksumstk = 0;
2185 for ( i = 0; i < (sizeof(idinfo) / sizeof(idinfo[0])); i += 1 )
2186 {
2187 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2188 {
2189 ((char *)&idinfo)[(i * 4) + j] = ((char *)0xBFBF0000)[(i * 4) + j];
2190 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2191 }
2192 chksumint += chksumstk;
2193 }
2194 for ( ; i < 0x4000; i += 1 )
2195 {
2196 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2197 {
2198 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2199 }
2200 chksumint += chksumstk;
2201 }
2202 if ( chksumint )
2203 {
2204 KPRINTF("# checksum error %d\n", chksumint);
2205 return 0;
2206 }
2207 if ( mode )
2208 {
2209 *buf = idinfo[11];
2210 }
2211 else
2212 {
2213 *buf = idinfo[2];
2214 buf[1] = idinfo[3];
2215 }
2216 return 1;
2217}
2218
2219static int query_boot_mode_6_nonzero()
2220{
2221 int *BootMode;
2222
2223 BootMode = QueryBootMode(6);
2224 return !(!BootMode || (*(u16 *)BootMode & 0xFFFC) != 0x60);
2225}
2226
2227static int query_boot_mode_6_zero()
2228{
2229 return !QueryBootMode(6);
2230}
2231
2232static int cdvdman_readID(int mode, int *buf)
2233{
2234 u8 id_val[8];
2235 iop_sys_clock_t sysclk;
2236 u32 id_result;
2237
2238 id_result = -1;
2239 if ( query_boot_mode_6_nonzero() )
2240 {
2241 if ( read_id_from_rom(mode, buf) && mode == 1 )
2242 {
2243 if ( *buf == -1 )
2244 {
2245 *buf = 0x1A0002;
2246 }
2247 return 1;
2248 }
2249 return 0;
2250 }
2251 else
2252 {
2253 if ( query_boot_mode_6_zero() )
2254 {
2255 if ( !sceCdRI(id_val, &id_result) || id_result )
2256 {
2257 return 0;
2258 }
2259 }
2260 else
2261 {
2262 if ( !g_readid_systemtime.lo && !g_readid_systemtime.hi )
2263 {
2264 GetSystemTime(&sysclk);
2265 g_readid_systemtime = sysclk;
2266 }
2267 *(iop_sys_clock_t *)id_val = g_readid_systemtime;
2268 }
2269 if ( mode )
2270 {
2271 *buf = *(u32 *)id_val >> 8;
2272 }
2273 else
2274 {
2275 *buf = id_val[0] | 0x8004600;
2276 buf[1] = *(u32 *)&id_val[4];
2277 }
2278 return 1;
2279 }
2280}
2281
2282int sceCdReadGUID(u64 *guid)
2283{
2284 return cdvdman_readID(0, (int *)guid);
2285}
2286
2287int sceCdReadModelID(unsigned int *id)
2288{
2289 return cdvdman_readID(1, (int *)id);
2290}
2291#endif
2292
2293int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
2294{
2295 cdrom_stm_devctl_t devctl_req;
2296 int buf;
2297
2298 memset(&devctl_req, 0, sizeof(devctl_req));
2299 devctl_req.m_cmdid = 5;
2300 devctl_req.m_posszarg1 = bufmax;
2301 devctl_req.m_posszarg2 = bankmax;
2302 devctl_req.m_buffer = buffer;
2303 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2304}
2305
2306int sceCdStStart(u32 lbn, sceCdRMode *mode)
2307{
2308 cdrom_stm_devctl_t devctl_req;
2309 int buf;
2310
2311 memset(&devctl_req, 0, sizeof(devctl_req));
2312 devctl_req.m_rmode.datapattern = mode->datapattern;
2313 devctl_req.m_rmode.spindlctrl = mode->spindlctrl;
2314 devctl_req.m_cmdid = 1;
2315 devctl_req.m_posszarg1 = lbn;
2316 devctl_req.m_rmode.trycount = mode->trycount;
2317 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2318}
2319
2320int sceCdStSeekF(unsigned int lsn)
2321{
2322 cdrom_stm_devctl_t devctl_req;
2323 int buf;
2324
2325 memset(&devctl_req, 0, sizeof(devctl_req));
2326 devctl_req.m_cmdid = 9;
2327 devctl_req.m_posszarg1 = lsn;
2328 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2329}
2330
2331int sceCdStSeek(u32 lbn)
2332{
2333 cdrom_stm_devctl_t devctl_req;
2334 int buf;
2335
2336 memset(&devctl_req, 0, sizeof(devctl_req));
2337 devctl_req.m_posszarg1 = lbn;
2338 devctl_req.m_cmdid = 4;
2339 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2340}
2341
2342int sceCdStStop(void)
2343{
2344 cdrom_stm_devctl_t devctl_req;
2345 int buf;
2346
2347 memset(&devctl_req, 0, sizeof(devctl_req));
2348 devctl_req.m_cmdid = 3;
2349 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2350}
2351
2352int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
2353{
2354 cdrom_stm_devctl_t devctl_req;
2355 int buf;
2356
2357 (void)mode;
2358
2359 memset(&devctl_req, 0, sizeof(devctl_req));
2360 devctl_req.m_cmdid = 1;
2361 devctl_req.m_posszarg2 = sectors;
2362 devctl_req.m_buffer = buffer;
2363 if ( devctl("cdrom_stm0:", 0x4394, &devctl_req, sizeof(devctl_req), &buf, 4) < 0 )
2364 {
2365 buf = 0;
2366 }
2367 *error = devctl_req.m_error;
2368 return buf;
2369}
2370
2371int sceCdStPause(void)
2372{
2373 cdrom_stm_devctl_t devctl_req;
2374 int buf;
2375
2376 memset(&devctl_req, 0, sizeof(devctl_req));
2377 devctl_req.m_cmdid = 7;
2378 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2379}
2380
2381int sceCdStResume(void)
2382{
2383 cdrom_stm_devctl_t devctl_req;
2384 int buf;
2385
2386 memset(&devctl_req, 0, sizeof(devctl_req));
2387 devctl_req.m_cmdid = 8;
2388 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2389}
2390
2391int sceCdStStat(void)
2392{
2393 cdrom_stm_devctl_t devctl_req;
2394 int buf;
2395
2396 memset(&devctl_req, 0, sizeof(devctl_req));
2397 devctl_req.m_cmdid = 6;
2398 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2399}
2400
2401static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer)
2402{
2403 int parent_level;
2404 int i;
2405 unsigned int j;
2406 char name_buf[32];
2407
2408 VERBOSE_PRINTF(1, "CdSearchFile: start name= %s layer= %d\n", name, layer);
2409 if ( g_cdvdman_fs_layer != layer )
2410 {
2411 g_cdvdman_fs_cache = 0;
2412 }
2413 if ( !cdvdman_mediactl(0) && g_cdvdman_fs_cache )
2414 {
2415 VERBOSE_KPRINTF(1, "CdSearchFile: cache dir data used\n");
2416 }
2417 else
2418 {
2419 VERBOSE_PRINTF(1, "CdSearchFile Topen= %s\n", name);
2420 if ( !CD_newmedia(layer) )
2421 {
2422 g_cdvdman_fs_cache = 0;
2423 return 0;
2424 }
2425 g_cdvdman_fs_cache = 1;
2426 }
2427 if ( *name != '\\' )
2428 {
2429 return 0;
2430 }
2431 name_buf[0] = 0;
2432 parent_level = 1;
2433 j = 0;
2434 for ( i = 0; i < 8 && name[i]; i += 1 )
2435 {
2436 for ( j = 0; name[i + j] != '\\'; j += 1 )
2437 {
2438 name_buf[j] = name[i + j];
2439 }
2440 name_buf[j] = 0;
2441 parent_level = cdvdman_finddir(parent_level, name_buf);
2442 if ( parent_level == -1 )
2443 {
2444 name_buf[0] = 0;
2445 break;
2446 }
2447 }
2448 if ( i >= 8 )
2449 {
2450 VERBOSE_PRINTF(1, "%s: path level (%d) error\n", name, i);
2451 return 0;
2452 }
2453 if ( !name_buf[0] )
2454 {
2455 VERBOSE_PRINTF(1, "%s: dir was not found\n", name);
2456 return 0;
2457 }
2458 name_buf[j] = 0;
2459 if ( !CD_cachefile(parent_level, layer) )
2460 {
2461 VERBOSE_PRINTF(1, "CdSearchFile: disc error\n");
2462 return 0;
2463 }
2464 VERBOSE_PRINTF(2, "CdSearchFile: searching %s...\n", name_buf);
2465 for ( j = 0;
2466 j < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) && g_cdvdman_filetbl[j].m_file_struct.name[0];
2467 j += 1 )
2468 {
2469 VERBOSE_PRINTF(1, "%d %s %s\n", (int)j, g_cdvdman_filetbl[j].m_file_struct.name, name_buf);
2470 if ( cdvdman_cmpname(g_cdvdman_filetbl[j].m_file_struct.name, name_buf) )
2471 {
2472 VERBOSE_PRINTF(2, "%s:\t found\n", name_buf);
2473 // The following memcpy was inlined
2474 memcpy(fp, &g_cdvdman_filetbl[j], sizeof(cdvdman_filetbl_entry_t));
2475 fp->m_file_struct.lsn += layer ? g_cdvdman_fs_base2 : 0;
2476 return 1;
2477 }
2478 }
2479 VERBOSE_PRINTF(1, "%s: not found\n", name_buf);
2480 return 0;
2481}
2482
2483static int sceCdSearchDir(char *dirname, int layer)
2484{
2485 sceCdlFILE fp;
2486
2487 VERBOSE_PRINTF(1, "_sceCdSearchDir: dir name %s layer %d\n", dirname, layer);
2488 return sceCdLayerSearchFile(&fp, dirname, layer) ? g_cdvdman_fs_cdsec : SCECdErREADCFR;
2489}
2490
2491static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer)
2492{
2493 VERBOSE_PRINTF(1, "_sceCdReadDir: current= %d dsec= %d layer= %d\n", g_cdvdman_fs_cdsec, dsec, layer);
2494 if ( g_cdvdman_fs_cdsec != dsec || g_cdvdman_fs_layer != layer )
2495 {
2496 if ( g_cdvdman_fs_layer != layer )
2497 {
2498 if ( !CD_newmedia(layer) )
2499 {
2500 return -ENOENT;
2501 }
2502 g_cdvdman_fs_cache = 1;
2503 }
2504 if ( !CD_cachefile(dsec, layer) )
2505 {
2506 return -ENOENT;
2507 }
2508 }
2509 if ( g_cdvdman_filetbl[index].m_file_struct.name[0] )
2510 {
2511 VERBOSE_PRINTF(1, "%s:\t found dir_point %d\n", g_cdvdman_filetbl[index].m_file_struct.name, index);
2512 // The following memcpy was inlined
2513 memcpy(fp, &g_cdvdman_filetbl[index], sizeof(cdvdman_filetbl_entry_t));
2514 return 1;
2515 }
2516 return 0;
2517}
2518
2519static int cdvdman_cmpname(const char *p, const char *q)
2520{
2521 return !strncmp(p, q, 12);
2522}
2523
2524static int CD_newmedia(int arg)
2525{
2526 unsigned int DiskType;
2527 unsigned int i;
2528 iso9660_path_t *path_cur;
2529 int state;
2530 int ptsector;
2531
2532 ptsector = 0;
2533 DiskType = sceCdGetDiskType();
2534 switch ( DiskType )
2535 {
2536 case SCECdPSCD:
2537 case SCECdPSCDDA:
2538 case SCECdPS2CD:
2539 case SCECdPS2CDDA:
2540 case SCECdPS2DVD:
2541 case SCECdDVDVR:
2542 case SCECdDVDV:
2543 case SCECdIllegalMedia:
2544 break;
2545 default:
2546 VERBOSE_PRINTF(1, "CD_newmedia: Illegal disc media type =%d\n", (int)DiskType);
2547 return 0;
2548 }
2549 g_cdvdman_fs_base2 = 0;
2550 if ( DiskType == SCECdPS2DVD )
2551 {
2552 if ( !DvdDual_infochk() )
2553 {
2554 VERBOSE_PRINTF(1, "CD_newmedia: Get DvdDual_infochk fail\n");
2555 return 0;
2556 }
2557 g_cdvdman_fs_base2 = arg ? g_cdvdman_istruct.m_layer_1_lsn : 0;
2558 }
2559 if ( disc_read(1, g_cdvdman_fs_base2 + 0x10, g_cdvdman_fs_rbuf, arg) != 1 )
2560 {
2561 VERBOSE_PRINTF(1, "CD_newmedia: Read error in disc_read(PVD)\n");
2562 return 0;
2563 }
2564 CpuSuspendIntr(&state);
2565 for ( i = 0; i < g_cdvdman_pathtblsize; i += 1 )
2566 {
2567 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
2568 g_cdvdman_pathtbl[i].m_layer = 0;
2569 g_cdvdman_pathtbl[i].m_nsec = 0;
2570 g_cdvdman_pathtbl[i].m_lsn = 0;
2571 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
2572 }
2573 g_cache_count = 0;
2574 g_cache_table = 0;
2575 g_cache_path_size = 0;
2576 CpuResumeIntr(state);
2577 if ( strncmp((char *)((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_id, "CD001", 5) )
2578 {
2579 VERBOSE_PRINTF(1, "CD_newmedia: Disc format error in cd_read(PVD)\n");
2580 return 0;
2581 }
2582 switch ( DiskType )
2583 {
2584 case SCECdPSCD:
2585 case SCECdPSCDDA:
2586 case SCECdPS2CD:
2587 case SCECdPS2CDDA:
2588 VERBOSE_PRINTF(1, "CD_newmedia: CD Read mode\n");
2589 ptsector = *(u32 *)(((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_type_l_path_table);
2590 break;
2591 case SCECdPS2DVD:
2592 case SCECdDVDVR:
2593 case SCECdDVDV:
2594 VERBOSE_PRINTF(1, "CD_newmedia: DVD Read mode\n");
2595 ptsector = 257;
2596 break;
2597 }
2598 if ( disc_read(1, g_cdvdman_fs_base2 + ptsector, g_cdvdman_fs_rbuf, arg) != 1 )
2599 {
2600 VERBOSE_PRINTF(1, "CD_newmedia: Read error (PT:%08x)\n", ptsector);
2601 return 0;
2602 }
2603 VERBOSE_PRINTF(2, "CD_newmedia: sarching dir..\n");
2604 for ( i = 0, path_cur = (iso9660_path_t *)g_cdvdman_fs_rbuf;
2605 i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0]))
2606 && path_cur < (iso9660_path_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)] && path_cur->m_name_len[0];
2607 i += 1,
2608 path_cur = (iso9660_path_t *)(((char *)path_cur) + path_cur->m_name_len[0] + (path_cur->m_name_len[0] & 1)
2609 + sizeof(iso9660_path_t)) )
2610 {
2611 memcpy(&g_cdvdman_dirtbl[i].m_extent, path_cur->m_extent, sizeof(path_cur->m_extent));
2612 g_cdvdman_dirtbl[i].m_number = i;
2613 memcpy(&g_cdvdman_dirtbl[i].m_parent, path_cur->m_parent, sizeof(path_cur->m_parent));
2614 memcpy(g_cdvdman_dirtbl[i].m_name, path_cur->m_name, path_cur->m_name_len[0]);
2615 g_cdvdman_dirtbl[i].m_name[path_cur->m_name_len[0]] = 0;
2616 VERBOSE_PRINTF(
2617 2,
2618 "\t%08x,%04x,%04x,%s\n",
2619 g_cdvdman_dirtbl[i].m_extent,
2620 g_cdvdman_dirtbl[i].m_number,
2621 g_cdvdman_dirtbl[i].m_parent,
2622 g_cdvdman_dirtbl[i].m_name);
2623 }
2624 if ( i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) )
2625 {
2626 g_cdvdman_dirtbl[i].m_parent = 0;
2627 }
2628 g_cdvdman_fs_cdsec = 0;
2629 g_cdvdman_fs_layer = arg;
2630 VERBOSE_PRINTF(2, "CD_newmedia: %d dir entries found\n", (int)i);
2631 return 1;
2632}
2633
2634static int cdvdman_finddir(int target_parent, const char *target_name)
2635{
2636 unsigned int i;
2637
2638 for ( i = 0; i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) && g_cdvdman_dirtbl[i].m_parent; i += 1 )
2639 {
2640 if ( g_cdvdman_dirtbl[i].m_parent == target_parent && !strcmp(target_name, g_cdvdman_dirtbl[i].m_name) )
2641 {
2642 return i + 1;
2643 }
2644 }
2645 return -1;
2646}
2647
2648static int CD_cachefile(int dsec, int layer)
2649{
2650 iso9660_dirent_t *dirent_cur;
2651 unsigned int i;
2652
2653 if ( dsec == g_cdvdman_fs_cdsec )
2654 {
2655 return 1;
2656 }
2657 if (
2658 disc_read(1, g_cdvdman_dirtbl[dsec - 1].m_extent + (layer ? g_cdvdman_fs_base2 : 0), g_cdvdman_fs_rbuf, layer)
2659 != 1 )
2660 {
2661 VERBOSE_PRINTF(1, "CD_cachefile: dir not found\n");
2662 g_cdvdman_fs_cdsec = 0;
2663 return 0;
2664 }
2665 VERBOSE_PRINTF(2, "CD_cachefile: searching...\n");
2666 for ( i = 0, dirent_cur = (iso9660_dirent_t *)g_cdvdman_fs_rbuf;
2667 i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0]))
2668 && dirent_cur < (iso9660_dirent_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)];
2669 i += 1, dirent_cur = (iso9660_dirent_t *)((char *)dirent_cur + dirent_cur->m_length[0]) )
2670 {
2671 int file_year;
2672
2673 if ( !dirent_cur->m_length[0] )
2674 {
2675 break;
2676 }
2677 memcpy(
2678 &g_cdvdman_filetbl[i].m_file_struct.lsn, dirent_cur->m_extent, sizeof(g_cdvdman_filetbl[i].m_file_struct.lsn));
2679 memcpy(
2680 &g_cdvdman_filetbl[i].m_file_struct.size, dirent_cur->m_size, sizeof(g_cdvdman_filetbl[i].m_file_struct.size));
2681 file_year = dirent_cur->m_date[0] + 1900;
2682 g_cdvdman_filetbl[i].m_file_struct.date[7] = file_year >> 8;
2683 g_cdvdman_filetbl[i].m_file_struct.date[6] = file_year;
2684 g_cdvdman_filetbl[i].m_file_struct.date[5] = dirent_cur->m_date[1];
2685 g_cdvdman_filetbl[i].m_file_struct.date[4] = dirent_cur->m_date[2];
2686 g_cdvdman_filetbl[i].m_file_struct.date[3] = dirent_cur->m_date[3];
2687 g_cdvdman_filetbl[i].m_file_struct.date[2] = dirent_cur->m_date[4];
2688 g_cdvdman_filetbl[i].m_file_struct.date[1] = dirent_cur->m_date[5];
2689 g_cdvdman_filetbl[i].m_flags = dirent_cur->m_flags[0];
2690 switch ( i )
2691 {
2692 case 0:
2693 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, ".");
2694 break;
2695 case 1:
2696 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, "..");
2697 break;
2698 default:
2699 memcpy(g_cdvdman_filetbl[i].m_file_struct.name, dirent_cur->m_name, dirent_cur->m_name_len[0]);
2700 g_cdvdman_filetbl[i].m_file_struct.name[dirent_cur->m_name_len[0]] = 0;
2701 break;
2702 }
2703 VERBOSE_PRINTF(
2704 2,
2705 "\t lsn %d size %d name:%d:%s %d/%d/%d %d:%d:%d\n",
2706 (int)(g_cdvdman_filetbl[i].m_file_struct.lsn),
2707 (int)(g_cdvdman_filetbl[i].m_file_struct.size),
2708 dirent_cur->m_name_len[0],
2709 g_cdvdman_filetbl[i].m_file_struct.name,
2710 file_year,
2711 g_cdvdman_filetbl[i].m_file_struct.date[5],
2712 g_cdvdman_filetbl[i].m_file_struct.date[4],
2713 g_cdvdman_filetbl[i].m_file_struct.date[3],
2714 g_cdvdman_filetbl[i].m_file_struct.date[2],
2715 g_cdvdman_filetbl[i].m_file_struct.date[1]);
2716 }
2717 g_cdvdman_fs_cdsec = dsec;
2718 if ( i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) )
2719 {
2720 g_cdvdman_filetbl[i].m_file_struct.name[0] = 0;
2721 }
2722 VERBOSE_PRINTF(2, "CD_cachefile: %d files found\n", (int)i);
2723 return 1;
2724}
2725
2726static int disc_read(int size, int loc, void *buffer, int layer)
2727{
2728 int f;
2729 int i;
2730 sceCdRMode rmode;
2731 int has_success;
2732
2733 has_success = 1;
2734 f = 0;
2735 rmode.trycount = 16;
2736 VERBOSE_PRINTF(1, "cd_read:lsn= %d size= %d layer= %d\n", loc, size, layer);
2737 if ( cdvdman_l0check(layer) )
2738 {
2739 g_cdvdman_srchspd = 0;
2740 }
2741 switch ( g_cdvdman_srchspd )
2742 {
2743 case SCECdSpinX1:
2744 case SCECdSpinX2:
2745 case SCECdSpinX4:
2746 rmode.spindlctrl = g_cdvdman_srchspd;
2747 break;
2748 case SCECdSpinStm:
2749 case SCECdSpinNom:
2750 rmode.spindlctrl = !!g_cdvdman_srchspd;
2751 break;
2752 default:
2753 rmode.spindlctrl = SCECdSpinNom;
2754 break;
2755 }
2756 rmode.datapattern = SCECdSecS2048;
2757 if ( !g_cdvdman_pathtblflag )
2758 {
2759 has_success = 1;
2760 }
2761 if ( !has_success )
2762 {
2763 int pathcachecnt;
2764
2765 pathcachecnt = (g_cache_count < g_cdvdman_pathtblsize) ? g_cache_count : g_cdvdman_pathtblsize;
2766 for ( i = 0; i < pathcachecnt; i += 1 )
2767 {
2768 VERBOSE_KPRINTF(
2769 1,
2770 "Path table Cache Search lsn:%d:%d nsec:%d:%d layer%d:%d\n",
2771 g_cdvdman_pathtbl[i].m_lsn,
2772 loc,
2773 g_cdvdman_pathtbl[i].m_nsec,
2774 size,
2775 g_cdvdman_pathtbl[i].m_layer,
2776 layer);
2777 if (
2778 g_cdvdman_pathtbl[i].m_lsn == loc && g_cdvdman_pathtbl[i].m_nsec == (unsigned int)size
2779 && g_cdvdman_pathtbl[i].m_layer == layer )
2780 {
2781 break;
2782 }
2783 }
2784 if ( i != pathcachecnt )
2785 {
2786 VERBOSE_KPRINTF(1, "Path table Cache ON:%d\n", g_cdvdman_pathtbl[i].m_cache_path_sz);
2787 if ( lseek(g_cache_path_fd, g_cdvdman_pathtbl[i].m_cache_path_sz, 0) >= 0 )
2788 {
2789 read(g_cache_path_fd, buffer, size << 11);
2790 f = 1;
2791 g_cdvdman_pathtbl[i].m_cache_hit_count += 1;
2792 }
2793 has_success = 1;
2794 }
2795 if ( !has_success )
2796 {
2797 if ( !sceCdRE(loc, size, buffer, &rmode) )
2798 {
2799 return 0;
2800 }
2801 sceCdSync(3);
2802 }
2803 }
2804 if ( !has_success && !sceCdGetError() )
2805 {
2806 int cache_path_sz;
2807
2808 if ( g_cache_count >= g_cdvdman_pathtblsize )
2809 {
2810 int cachetblo1;
2811 unsigned int cacheblo2;
2812
2813 g_cache_table += 1;
2814 if ( g_cache_table >= g_cdvdman_pathtblsize )
2815 {
2816 g_cache_table = 0;
2817 }
2818 cachetblo1 = g_cache_table;
2819 cacheblo2 = cachetblo1;
2820 for ( i = 0; (unsigned int)i < g_cache_count; i += 1 )
2821 {
2822 if ( cacheblo2 >= g_cdvdman_pathtblsize )
2823 {
2824 cacheblo2 = 0;
2825 }
2826 if (
2827 g_cdvdman_pathtbl[cacheblo2].m_nsec >= (unsigned int)size
2828 && g_cdvdman_pathtbl[cacheblo2].m_cache_hit_count
2829 < (unsigned int)g_cdvdman_pathtbl[cachetblo1].m_cache_hit_count )
2830 {
2831 cachetblo1 = cacheblo2;
2832 }
2833 cacheblo2 += 1;
2834 }
2835 cache_path_sz = g_cdvdman_pathtbl[cachetblo1].m_cache_path_sz;
2836 g_cache_table = cachetblo1;
2837 }
2838 else
2839 {
2840 cache_path_sz = g_cache_path_size;
2841 g_cache_table = g_cache_count;
2842 g_cache_count += 1;
2843 }
2844 if ( lseek(g_cache_path_fd, cache_path_sz, 0) >= 0 )
2845 {
2846 int ptbl_wcache_write_res;
2847
2848 ptbl_wcache_write_res = write(g_cache_path_fd, buffer, size << 11);
2849 if ( ptbl_wcache_write_res == size << 11 )
2850 {
2851 f = 1;
2852 g_cdvdman_pathtbl[g_cache_table].m_cache_path_sz = cache_path_sz;
2853 g_cdvdman_pathtbl[g_cache_table].m_lsn = loc;
2854 g_cdvdman_pathtbl[g_cache_table].m_nsec = size;
2855 g_cdvdman_pathtbl[g_cache_table].m_layer = layer;
2856 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
2857 g_cache_path_size += (g_cache_count < g_cdvdman_pathtblsize) ? ptbl_wcache_write_res : 0;
2858 }
2859 else
2860 {
2861 VERBOSE_KPRINTF(1, "Ptbl_WCache:write %d", ptbl_wcache_write_res);
2862 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
2863 g_cdvdman_pathtbl[g_cache_table].m_layer = 0;
2864 g_cdvdman_pathtbl[g_cache_table].m_nsec = 0;
2865 g_cdvdman_pathtbl[g_cache_table].m_lsn = 0;
2866 }
2867 }
2868 has_success = 1;
2869 }
2870 if ( has_success )
2871 {
2872 if ( f )
2873 {
2874 return size;
2875 }
2876 if ( !sceCdRE(loc, size, buffer, &rmode) )
2877 {
2878 return 0;
2879 }
2880 sceCdSync(3);
2881 if ( !sceCdGetError() )
2882 {
2883 return size;
2884 }
2885 }
2886 VERBOSE_KPRINTF(1, "cd_read: error code %x\n", sceCdGetError());
2887 return 0;
2888}
2889
2890static int path_tbl_init(u32 blocks, char *fname, int action)
2891{
2892 int num;
2893 int v;
2894 char cachedir[512];
2895 int state;
2896 u32 blocksbs;
2897
2898 num = 0;
2899 v = 0;
2900 if ( action )
2901 {
2902 CpuSuspendIntr(&state);
2903 g_cdvdman_pathtbl = (cdvdman_pathtbl_t *)AllocSysMemory(ALLOC_LAST, sizeof(cdvdman_pathtbl_t) * blocks, 0);
2904 if ( !g_cdvdman_pathtbl )
2905 {
2906 CpuResumeIntr(state);
2907 g_cdvdman_pathtblflag = 0;
2908 return -ENOMEM;
2909 }
2910 CpuResumeIntr(state);
2911 sprintf(cachedir, "%sCache_Path", fname);
2912 v = open(cachedir, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
2913 if ( v >= 0 )
2914 {
2915 u32 i;
2916
2917 g_cache_path_fd = v;
2918 if ( !strncmp(cachedir, "pfs", 3) )
2919 {
2920 blocksbs = blocks << 11;
2921 ioctl2(g_cache_path_fd, PIOCALLOC, &blocksbs, 4, 0, 0);
2922 }
2923 for ( i = 0; i < blocks; i += 1 )
2924 {
2925 v = write(g_cache_path_fd, g_cdvdman_fs_rbuf, sizeof(g_cdvdman_fs_rbuf));
2926 if ( v < 0 )
2927 {
2928 break;
2929 }
2930 }
2931 if ( v >= 0 )
2932 {
2933 CpuSuspendIntr(&state);
2934 g_cdvdman_pathtblsize = blocks;
2935 for ( i = 0; i < blocks; i += 1 )
2936 {
2937 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
2938 g_cdvdman_pathtbl[i].m_layer = 0;
2939 g_cdvdman_pathtbl[i].m_nsec = 0;
2940 g_cdvdman_pathtbl[i].m_lsn = 0;
2941 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
2942 }
2943 g_cache_path_size = 0;
2944 g_cache_count = 0;
2945 g_cache_table = 0;
2946 g_cdvdman_pathtblflag = 1;
2947 CpuResumeIntr(state);
2948 return 0;
2949 }
2950 }
2951 }
2952 if ( g_cache_path_fd != -1 )
2953 {
2954 num = close(g_cache_path_fd);
2955 if ( num >= 0 )
2956 {
2957 if ( !strncmp(cachedir, "pfs", 3) )
2958 {
2959 num = remove(cachedir);
2960 }
2961 else if ( !strncmp(cachedir, "host", 4) )
2962 {
2963 num = 0;
2964 remove(cachedir);
2965 }
2966 }
2967 }
2968 CpuSuspendIntr(&state);
2969 g_cache_path_fd = -1;
2970 g_cache_count = 0;
2971 g_cache_table = 0;
2972 g_cache_path_size = 0;
2973 g_cdvdman_pathtblflag = 0;
2974 g_cdvdman_pathtblsize = 0;
2975 FreeSysMemory(g_cdvdman_pathtbl);
2976 g_cdvdman_pathtbl = 0;
2977 CpuResumeIntr(state);
2978 if ( v < 0 )
2979 {
2980 VERBOSE_KPRINTF(1, "path_tbl_init Error %d\n", v);
2981 }
2982 return (!action) ? num : v;
2983}
2984
2985// Unofficial: unused obfuscation code was removed
2986
2987// clang-format off
2988__asm__ (
2989 "\t" ".set push" "\n"
2990 "\t" ".set noat" "\n"
2991 "\t" ".set noreorder" "\n"
2992 "\t" ".global optimized_memcpy" "\n"
2993 "\t" "optimized_memcpy:" "\n"
2994 "\t" " srl $a3, $a2, 2" "\n"
2995 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
2996 "\t" " or $a3, $a0, $a1" "\n"
2997 "\t" " andi $a3, $a3, 0x3" "\n"
2998 "\t" " bnez $a3, .Loptimized_memcpy_3" "\n"
2999 "\t" " nop" "\n"
3000 "\t" " srl $a3, $a2, 2" "\n"
3001 "\t" " addiu $at, $zero, 0xC" "\n"
3002 "\t" " div $zero, $a3, $at" "\n"
3003 "\t" " mflo $a3" "\n"
3004 "\t" " mfhi $v1" "\n"
3005 "\t" " beqz $v1, .Loptimized_memcpy_2" "\n"
3006 "\t" " nop" "\n"
3007 "\t" ".Loptimized_memcpy_1:" "\n"
3008 "\t" " lw $v0, 0x0($a1)" "\n"
3009 "\t" " addiu $v1, $v1, -0x1" "\n"
3010 "\t" " sw $v0, 0x0($a0)" "\n"
3011 "\t" " addiu $a1, $a1, 0x4" "\n"
3012 "\t" " bnez $v1, .Loptimized_memcpy_1" "\n"
3013 "\t" " addiu $a0, $a0, 0x4" "\n"
3014 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3015 "\t" " nop" "\n"
3016 "\t" ".Loptimized_memcpy_2:" "\n"
3017 "\t" " lw $v0, 0x0($a1)" "\n"
3018 "\t" " lw $v1, 0x4($a1)" "\n"
3019 "\t" " lw $t0, 0x8($a1)" "\n"
3020 "\t" " lw $t1, 0xC($a1)" "\n"
3021 "\t" " lw $t2, 0x10($a1)" "\n"
3022 "\t" " lw $t3, 0x14($a1)" "\n"
3023 "\t" " lw $t4, 0x18($a1)" "\n"
3024 "\t" " lw $t5, 0x1C($a1)" "\n"
3025 "\t" " lw $t6, 0x20($a1)" "\n"
3026 "\t" " lw $t7, 0x24($a1)" "\n"
3027 "\t" " lw $t8, 0x28($a1)" "\n"
3028 "\t" " lw $t9, 0x2C($a1)" "\n"
3029 "\t" " addiu $a3, $a3, -0x1" "\n"
3030 "\t" " sw $v0, 0x0($a0)" "\n"
3031 "\t" " sw $v1, 0x4($a0)" "\n"
3032 "\t" " sw $t0, 0x8($a0)" "\n"
3033 "\t" " sw $t1, 0xC($a0)" "\n"
3034 "\t" " sw $t2, 0x10($a0)" "\n"
3035 "\t" " sw $t3, 0x14($a0)" "\n"
3036 "\t" " sw $t4, 0x18($a0)" "\n"
3037 "\t" " sw $t5, 0x1C($a0)" "\n"
3038 "\t" " sw $t6, 0x20($a0)" "\n"
3039 "\t" " sw $t7, 0x24($a0)" "\n"
3040 "\t" " sw $t8, 0x28($a0)" "\n"
3041 "\t" " sw $t9, 0x2C($a0)" "\n"
3042 "\t" " addiu $a1, $a1, 0x30" "\n"
3043 "\t" " bnez $a3, .Loptimized_memcpy_2" "\n"
3044 "\t" " addiu $a0, $a0, 0x30" "\n"
3045 "\t" " j .Loptimized_memcpy_12" "\n"
3046 "\t" " nop" "\n"
3047 "\t" ".Loptimized_memcpy_3:" "\n"
3048 "\t" " andi $a3, $a0, 0x3" "\n"
3049 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3050 "\t" " andi $a3, $a1, 0x3" "\n"
3051 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3052 "\t" " nop" "\n"
3053 "\t" " srl $a3, $a2, 2" "\n"
3054 "\t" " addiu $at, $zero, 0xC" "\n"
3055 "\t" " div $zero, $a3, $at" "\n"
3056 "\t" " mflo $a3" "\n"
3057 "\t" " mfhi $v1" "\n"
3058 "\t" " beqz $v1, .Loptimized_memcpy_5" "\n"
3059 "\t" " nop" "\n"
3060 "\t" ".Loptimized_memcpy_4:" "\n"
3061 "\t" " lwl $v0, 0x3($a1)" "\n"
3062 "\t" " lwr $v0, 0x0($a1)" "\n"
3063 "\t" " addiu $v1, $v1, -0x1" "\n"
3064 "\t" " swl $v0, 0x3($a0)" "\n"
3065 "\t" " swr $v0, 0x0($a0)" "\n"
3066 "\t" " addiu $a1, $a1, 0x4" "\n"
3067 "\t" " bnez $v1, .Loptimized_memcpy_4" "\n"
3068 "\t" " addiu $a0, $a0, 0x4" "\n"
3069 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3070 "\t" " nop" "\n"
3071 "\t" ".Loptimized_memcpy_5:" "\n"
3072 "\t" " lwl $v0, 0x3($a1)" "\n"
3073 "\t" " lwr $v0, 0x0($a1)" "\n"
3074 "\t" " lwl $v1, 0x7($a1)" "\n"
3075 "\t" " lwr $v1, 0x4($a1)" "\n"
3076 "\t" " lwl $t0, 0xB($a1)" "\n"
3077 "\t" " lwr $t0, 0x8($a1)" "\n"
3078 "\t" " lwl $t1, 0xF($a1)" "\n"
3079 "\t" " lwr $t1, 0xC($a1)" "\n"
3080 "\t" " lwl $t2, 0x13($a1)" "\n"
3081 "\t" " lwr $t2, 0x10($a1)" "\n"
3082 "\t" " lwl $t3, 0x17($a1)" "\n"
3083 "\t" " lwr $t3, 0x14($a1)" "\n"
3084 "\t" " lwl $t4, 0x1B($a1)" "\n"
3085 "\t" " lwr $t4, 0x18($a1)" "\n"
3086 "\t" " lwl $t5, 0x1F($a1)" "\n"
3087 "\t" " lwr $t5, 0x1C($a1)" "\n"
3088 "\t" " lwl $t6, 0x23($a1)" "\n"
3089 "\t" " lwr $t6, 0x20($a1)" "\n"
3090 "\t" " lwl $t7, 0x27($a1)" "\n"
3091 "\t" " lwr $t7, 0x24($a1)" "\n"
3092 "\t" " lwl $t8, 0x2B($a1)" "\n"
3093 "\t" " lwr $t8, 0x28($a1)" "\n"
3094 "\t" " lwl $t9, 0x2F($a1)" "\n"
3095 "\t" " lwr $t9, 0x2C($a1)" "\n"
3096 "\t" " addiu $a3, $a3, -0x1" "\n"
3097 "\t" " swl $v0, 0x3($a0)" "\n"
3098 "\t" " swr $v0, 0x0($a0)" "\n"
3099 "\t" " swl $v1, 0x7($a0)" "\n"
3100 "\t" " swr $v1, 0x4($a0)" "\n"
3101 "\t" " swl $t0, 0xB($a0)" "\n"
3102 "\t" " swr $t0, 0x8($a0)" "\n"
3103 "\t" " swl $t1, 0xF($a0)" "\n"
3104 "\t" " swr $t1, 0xC($a0)" "\n"
3105 "\t" " swl $t2, 0x13($a0)" "\n"
3106 "\t" " swr $t2, 0x10($a0)" "\n"
3107 "\t" " swl $t3, 0x17($a0)" "\n"
3108 "\t" " swr $t3, 0x14($a0)" "\n"
3109 "\t" " swl $t4, 0x1B($a0)" "\n"
3110 "\t" " swr $t4, 0x18($a0)" "\n"
3111 "\t" " swl $t5, 0x1F($a0)" "\n"
3112 "\t" " swr $t5, 0x1C($a0)" "\n"
3113 "\t" " swl $t6, 0x23($a0)" "\n"
3114 "\t" " swr $t6, 0x20($a0)" "\n"
3115 "\t" " swl $t7, 0x27($a0)" "\n"
3116 "\t" " swr $t7, 0x24($a0)" "\n"
3117 "\t" " swl $t8, 0x2B($a0)" "\n"
3118 "\t" " swr $t8, 0x28($a0)" "\n"
3119 "\t" " swl $t9, 0x2F($a0)" "\n"
3120 "\t" " swr $t9, 0x2C($a0)" "\n"
3121 "\t" " addiu $a1, $a1, 0x30" "\n"
3122 "\t" " bnez $a3, .Loptimized_memcpy_5" "\n"
3123 "\t" " addiu $a0, $a0, 0x30" "\n"
3124 "\t" " j .Loptimized_memcpy_12" "\n"
3125 "\t" " nop" "\n"
3126 "\t" ".Loptimized_memcpy_6:" "\n"
3127 "\t" " andi $a3, $a0, 0x3" "\n"
3128 "\t" " beqz $a3, .Loptimized_memcpy_9" "\n"
3129 "\t" " nop" "\n"
3130 "\t" " srl $a3, $a2, 2" "\n"
3131 "\t" " addiu $at, $zero, 0xC" "\n"
3132 "\t" " div $zero, $a3, $at" "\n"
3133 "\t" " mflo $a3" "\n"
3134 "\t" " mfhi $v1" "\n"
3135 "\t" " beqz $v1, .Loptimized_memcpy_8" "\n"
3136 "\t" " nop" "\n"
3137 "\t" ".Loptimized_memcpy_7:" "\n"
3138 "\t" " lw $v0, 0x0($a1)" "\n"
3139 "\t" " addiu $v1, $v1, -0x1" "\n"
3140 "\t" " swl $v0, 0x3($a0)" "\n"
3141 "\t" " swr $v0, 0x0($a0)" "\n"
3142 "\t" " addiu $a1, $a1, 0x4" "\n"
3143 "\t" " bnez $v1, .Loptimized_memcpy_7" "\n"
3144 "\t" " addiu $a0, $a0, 0x4" "\n"
3145 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3146 "\t" " nop" "\n"
3147 "\t" ".Loptimized_memcpy_8:" "\n"
3148 "\t" " lw $v0, 0x0($a1)" "\n"
3149 "\t" " lw $v1, 0x4($a1)" "\n"
3150 "\t" " lw $t0, 0x8($a1)" "\n"
3151 "\t" " lw $t1, 0xC($a1)" "\n"
3152 "\t" " lw $t2, 0x10($a1)" "\n"
3153 "\t" " lw $t3, 0x14($a1)" "\n"
3154 "\t" " lw $t4, 0x18($a1)" "\n"
3155 "\t" " lw $t5, 0x1C($a1)" "\n"
3156 "\t" " lw $t6, 0x20($a1)" "\n"
3157 "\t" " lw $t7, 0x24($a1)" "\n"
3158 "\t" " lw $t8, 0x28($a1)" "\n"
3159 "\t" " lw $t9, 0x2C($a1)" "\n"
3160 "\t" " addiu $a3, $a3, -0x1" "\n"
3161 "\t" " swl $v0, 0x3($a0)" "\n"
3162 "\t" " swr $v0, 0x0($a0)" "\n"
3163 "\t" " swl $v1, 0x7($a0)" "\n"
3164 "\t" " swr $v1, 0x4($a0)" "\n"
3165 "\t" " swl $t0, 0xB($a0)" "\n"
3166 "\t" " swr $t0, 0x8($a0)" "\n"
3167 "\t" " swl $t1, 0xF($a0)" "\n"
3168 "\t" " swr $t1, 0xC($a0)" "\n"
3169 "\t" " swl $t2, 0x13($a0)" "\n"
3170 "\t" " swr $t2, 0x10($a0)" "\n"
3171 "\t" " swl $t3, 0x17($a0)" "\n"
3172 "\t" " swr $t3, 0x14($a0)" "\n"
3173 "\t" " swl $t4, 0x1B($a0)" "\n"
3174 "\t" " swr $t4, 0x18($a0)" "\n"
3175 "\t" " swl $t5, 0x1F($a0)" "\n"
3176 "\t" " swr $t5, 0x1C($a0)" "\n"
3177 "\t" " swl $t6, 0x23($a0)" "\n"
3178 "\t" " swr $t6, 0x20($a0)" "\n"
3179 "\t" " swl $t7, 0x27($a0)" "\n"
3180 "\t" " swr $t7, 0x24($a0)" "\n"
3181 "\t" " swl $t8, 0x2B($a0)" "\n"
3182 "\t" " swr $t8, 0x28($a0)" "\n"
3183 "\t" " swl $t9, 0x2F($a0)" "\n"
3184 "\t" " swr $t9, 0x2C($a0)" "\n"
3185 "\t" " addiu $a1, $a1, 0x30" "\n"
3186 "\t" " bnez $a3, .Loptimized_memcpy_8" "\n"
3187 "\t" " addiu $a0, $a0, 0x30" "\n"
3188 "\t" " j .Loptimized_memcpy_12" "\n"
3189 "\t" " nop" "\n"
3190 "\t" ".Loptimized_memcpy_9:" "\n"
3191 "\t" " srl $a3, $a2, 2" "\n"
3192 "\t" " addiu $at, $zero, 0xC" "\n"
3193 "\t" " div $zero, $a3, $at" "\n"
3194 "\t" " mflo $a3" "\n"
3195 "\t" " mfhi $v1" "\n"
3196 "\t" " beqz $v1, .Loptimized_memcpy_11" "\n"
3197 "\t" " nop" "\n"
3198 "\t" ".Loptimized_memcpy_10:" "\n"
3199 "\t" " lwl $v0, 0x3($a1)" "\n"
3200 "\t" " lwr $v0, 0x0($a1)" "\n"
3201 "\t" " addiu $v1, $v1, -0x1" "\n"
3202 "\t" " sw $v0, 0x0($a0)" "\n"
3203 "\t" " addiu $a1, $a1, 0x4" "\n"
3204 "\t" " bnez $v1, .Loptimized_memcpy_10" "\n"
3205 "\t" " addiu $a0, $a0, 0x4" "\n"
3206 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3207 "\t" " nop" "\n"
3208 "\t" ".Loptimized_memcpy_11:" "\n"
3209 "\t" " lwl $v0, 0x3($a1)" "\n"
3210 "\t" " lwr $v0, 0x0($a1)" "\n"
3211 "\t" " lwl $v1, 0x7($a1)" "\n"
3212 "\t" " lwr $v1, 0x4($a1)" "\n"
3213 "\t" " lwl $t0, 0xB($a1)" "\n"
3214 "\t" " lwr $t0, 0x8($a1)" "\n"
3215 "\t" " lwl $t1, 0xF($a1)" "\n"
3216 "\t" " lwr $t1, 0xC($a1)" "\n"
3217 "\t" " lwl $t2, 0x13($a1)" "\n"
3218 "\t" " lwr $t2, 0x10($a1)" "\n"
3219 "\t" " lwl $t3, 0x17($a1)" "\n"
3220 "\t" " lwr $t3, 0x14($a1)" "\n"
3221 "\t" " lwl $t4, 0x1B($a1)" "\n"
3222 "\t" " lwr $t4, 0x18($a1)" "\n"
3223 "\t" " lwl $t5, 0x1F($a1)" "\n"
3224 "\t" " lwr $t5, 0x1C($a1)" "\n"
3225 "\t" " lwl $t6, 0x23($a1)" "\n"
3226 "\t" " lwr $t6, 0x20($a1)" "\n"
3227 "\t" " lwl $t7, 0x27($a1)" "\n"
3228 "\t" " lwr $t7, 0x24($a1)" "\n"
3229 "\t" " lwl $t8, 0x2B($a1)" "\n"
3230 "\t" " lwr $t8, 0x28($a1)" "\n"
3231 "\t" " lwl $t9, 0x2F($a1)" "\n"
3232 "\t" " lwr $t9, 0x2C($a1)" "\n"
3233 "\t" " addiu $a3, $a3, -0x1" "\n"
3234 "\t" " sw $v0, 0x0($a0)" "\n"
3235 "\t" " sw $v1, 0x4($a0)" "\n"
3236 "\t" " sw $t0, 0x8($a0)" "\n"
3237 "\t" " sw $t1, 0xC($a0)" "\n"
3238 "\t" " sw $t2, 0x10($a0)" "\n"
3239 "\t" " sw $t3, 0x14($a0)" "\n"
3240 "\t" " sw $t4, 0x18($a0)" "\n"
3241 "\t" " sw $t5, 0x1C($a0)" "\n"
3242 "\t" " sw $t6, 0x20($a0)" "\n"
3243 "\t" " sw $t7, 0x24($a0)" "\n"
3244 "\t" " sw $t8, 0x28($a0)" "\n"
3245 "\t" " sw $t9, 0x2C($a0)" "\n"
3246 "\t" " addiu $a1, $a1, 0x30" "\n"
3247 "\t" " bnez $a3, .Loptimized_memcpy_11" "\n"
3248 "\t" " addiu $a0, $a0, 0x30" "\n"
3249 "\t" ".Loptimized_memcpy_12:" "\n"
3250 "\t" " andi $v1, $a2, 0x3" "\n"
3251 "\t" " beqz $v1, .Loptimized_memcpy_14" "\n"
3252 "\t" " nop" "\n"
3253 "\t" ".Loptimized_memcpy_13:" "\n"
3254 "\t" " lb $v0, 0x0($a1)" "\n"
3255 "\t" " addiu $v1, $v1, -0x1" "\n"
3256 "\t" " sb $v0, 0x0($a0)" "\n"
3257 "\t" " addiu $a1, $a1, 0x1" "\n"
3258 "\t" " bnez $v1, .Loptimized_memcpy_13" "\n"
3259 "\t" " addiu $a0, $a0, 0x1" "\n"
3260 "\t" ".Loptimized_memcpy_14:" "\n"
3261 "\t" " addu $v0, $a2, $zero" "\n"
3262 "\t" " jr $ra" "\n"
3263 "\t" " nop" "\n"
3264 "\t" ".set pop" "\n"
3265);
3266// clang-format on
3267
3268#ifdef DEAD_CODE
3269void hex_dump(u8 *addr_start, int length)
3270{
3271 int i;
3272
3273 KPRINTF("Hex Dump addr %08x\n", addr_start);
3274 for ( i = 0; i < length; i += 1 )
3275 {
3276 if ( !(i & 0xF) && i )
3277 {
3278 PRINTF("\n");
3279 }
3280 KPRINTF(" %02x", addr_start[i]);
3281 }
3282 KPRINTF("\n");
3283}
3284#endif
3285
3286static int cdvdman_initcfg()
3287{
3288 int i;
3289 u8 m_version[5];
3290 u32 eflag;
3291
3292 eflag = 0;
3293 for ( i = 0; i <= 100; i += 1 )
3294 {
3295 unsigned int mvored;
3296
3297 if ( !sceCdGetMVersion(m_version, &eflag) && (eflag & 0x80) )
3298 {
3299 vDelayThread(2000);
3300 VERBOSE_KPRINTF(1, "_sceCdMV error\n");
3301 }
3302 mvored = m_version[3] | (m_version[2] << 8) | (m_version[1] << 16);
3303 g_cdvdman_emudvd9 = m_version[2] & 1;
3304 VERBOSE_KPRINTF(1, "MV %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3305 g_cdvdman_minver_10700 = mvored >= 0x10700;
3306 g_cdvdman_minver_20200 = mvored >= 0x20200;
3307 g_cdvdman_minver_20400 = mvored >= 0x20400;
3308 g_cdvdman_minver_20800 = mvored >= 0x20800;
3309 g_cdvdman_minver_50000 = mvored >= 0x50000;
3310 g_cdvdman_minver_50200 = mvored >= 0x50200;
3311 g_cdvdman_minver_50400 = mvored >= 0x50400;
3312 g_cdvdman_minver_50600 = mvored >= 0x50600;
3313 g_cdvdman_minver_x_model_15 = (mvored & 0xF) == 1;
3314 g_cdvdman_minver_60000 = mvored >= 0x60000;
3315 g_cdvdman_minver_60200 = mvored >= 0x60200;
3316 return 1;
3317 }
3318 return 0;
3319}
3320
3321static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *), void *arg)
3322{
3323 return (QueryIntrContext() ? iSetAlarm : SetAlarm)(sys_clock, alarm_cb, arg);
3324}
3325
3326static int vCancelAlarm(unsigned int (*alarm_cb)(void *), void *arg)
3327{
3328 return (QueryIntrContext() ? iCancelAlarm : CancelAlarm)(alarm_cb, arg);
3329}
3330
3331#ifdef DEAD_CODE
3332s32 vSignalSema(s32 sema_id)
3333{
3334 return (QueryIntrContext() ? iSignalSema : SignalSema)(sema_id);
3335}
3336#endif
3337
3338static int vSetEventFlag(int ef, u32 bits)
3339{
3340 return (QueryIntrContext() ? iSetEventFlag : SetEventFlag)(ef, bits);
3341}
3342
3343static int vClearEventFlag(int ef, u32 bits)
3344{
3345 return (QueryIntrContext() ? iClearEventFlag : ClearEventFlag)(ef, bits);
3346}
3347
3348static int vReferEventFlagStatus(int ef, iop_event_info_t *info)
3349{
3350 return (QueryIntrContext() ? iReferEventFlagStatus : ReferEventFlagStatus)(ef, info);
3351}
3352
3353static int vDelayThread(int usec)
3354{
3355 int intrval;
3356 int state;
3357
3358 intrval = CpuSuspendIntr(&state);
3359 CpuResumeIntr(state);
3360 return (!QueryIntrContext() && !intrval) ? DelayThread(usec) : 0;
3361}
3362
3363static int read_timeout_alarm_cb(const iop_sys_clock_t *sys_clock)
3364{
3365 int read_timeout;
3366
3367 read_timeout = sys_clock->lo / 0x9000;
3368 KPRINTF("Read Time Out %d(msec)\n", read_timeout);
3369 sceCdSC(0xFFFFFFEE, &read_timeout);
3370 return !sceCdBreak();
3371}
3372
3374{
3375 void (*rc)(int);
3376 u32 efbits;
3377
3378 if ( sceCdSync(1) || PollEventFlag(g_ncmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
3379 {
3380 return 0;
3381 }
3382 rc = g_cdvdman_user_cb;
3383 g_cdvdman_user_cb = function;
3384 vSetEventFlag(g_ncmd_evid, 1);
3385 return rc;
3386}
3387
3388void *sceCdPOffCallback(void (*func)(void *), void *addr)
3389{
3390 void (*old_cb)(void *);
3391 int state;
3392
3393 CpuSuspendIntr(&state);
3394 old_cb = g_cdvdman_poff_cb;
3395 g_cdvdman_poff_cb = func;
3396 g_cdvdman_poffarg = addr;
3397 CpuResumeIntr(state);
3398 return old_cb;
3399}
3400
3401int sceCdstm0Cb(void (*p)(int))
3402{
3403 g_cdvdman_cdstm0cb = p;
3404 return 0;
3405}
3406
3407int sceCdstm1Cb(void (*p)(int))
3408{
3409 g_cdvdman_cdstm1cb = p;
3410 return 0;
3411}
3412
3413static int cdvdman_intr_cb(cdvdman_internal_struct_t *s)
3414{
3415 sceCdRMode cdrmode;
3416 int oldstate;
3417 int ext_passthrough;
3418 USE_DEV5_MMIO_HWPORT();
3419
3420 ext_passthrough = 0;
3421 s->m_wait_flag = s->m_waf_set_test;
3422 iSetEventFlag(g_cdvdman_intr_efid, 0x29);
3423 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
3424 if ( *(u16 *)&s->m_cdvdman_command == 0x3105 )
3425 {
3426 s->m_last_error = (sceCdStatus() == -1) ? SCECdErTRMOPN : 0;
3427 }
3428 if ( s->m_last_error == SCECdErEOM )
3429 {
3430 s->m_last_error = 0;
3431 }
3432 VERBOSE_KPRINTF(
3433 1, "Intr call func_num: %d Err= %02x OnTout= %d\n", g_cdvdman_cmdfunc, (u8)s->m_last_error, s->m_last_read_timeout);
3434 if ( !s->m_scmd_flag )
3435 {
3436 cdvdman_write_scmd(s);
3437 }
3438 if (
3439 (((u8)s->m_last_error == SCECdErREAD && g_cdvdman_cmdfunc == SCECdFuncRead)
3440 || ((u8)s->m_last_error == 1 && s->m_last_read_timeout && g_cdvdman_last_cmdfunc == 1))
3441 && !g_cdvdman_minver_20200 && !s->m_stream_flag && !s->m_dvd_flag && !s->m_recover_status
3442 && s->m_read_mode.trycount != 1 )
3443 {
3444 s->m_sync_error = 0;
3445 s->m_interupt_read_state = 0;
3446 if ( s->m_dec_mode_set )
3447 {
3448 s->m_dec_mode_last_set = 1;
3449 }
3450 else
3451 {
3452 VERBOSE_KPRINTF(1, "dec mode 0x00\n");
3453 s->m_read_chunk_reprocial_32 = 1 + (0x20 / ((!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk));
3454 s->m_dintrlsn = (s->m_read_lsn < 0x61) ? (s->m_read_lsn + s->m_read_sectors + 48) : (s->m_read_lsn - 80);
3455 s->m_read_mode.spindlctrl = 16;
3456 if ( !sceCdRead0_Rty(
3457 s->m_dintrlsn,
3458 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
3459 s->m_read_buf,
3460 &s->m_read_mode,
3461 (u8)s->m_cdvdman_command,
3462 0,
3463 0) )
3464 {
3465 s->m_last_error = SCECdErREAD;
3466 s->m_recover_status = 0;
3467 }
3468 else
3469 {
3470 ext_passthrough = 1;
3471 }
3472 }
3473 }
3474 if ( !ext_passthrough )
3475 {
3476 char dev5_reg_013_masked;
3477
3478 VERBOSE_KPRINTF(1, "Recover_Stat:%d\n", s->m_recover_status);
3479 dev5_reg_013_masked = dev5_mmio_hwport->m_dev5_reg_013 & 0xF;
3480 if ( dev5_reg_013_masked )
3481 {
3482 if (
3483 ((u8)s->m_last_error == 48 || ((u8)s->m_last_error == 1 && s->m_last_read_timeout)) && !s->m_recover_status
3484 && !s->m_stream_flag && g_cdvdman_cmdfunc != 9 && g_cdvdman_cmdfunc != SCECdFuncReadCDDA
3485 && (unsigned int)s->m_read_mode.trycount - 1 >= 4 )
3486 {
3487 s->m_sync_error = 0;
3488 s->m_interupt_read_state = 0;
3489 if ( s->m_dec_mode_set )
3490 {
3491 s->m_dec_mode_last_set = 2;
3492 }
3493 else
3494 {
3495 VERBOSE_KPRINTF(1, "dec mode 0x01\n");
3496 cdrmode.trycount = s->m_read_mode.trycount;
3497 cdrmode.spindlctrl = dev5_reg_013_masked + 13;
3498 cdrmode.datapattern = s->m_read_mode.datapattern;
3499 if ( sceCdRead0_Rty(
3500 s->m_read_lsn,
3501 s->m_read_sectors,
3502 s->m_read_buf,
3503 &cdrmode,
3504 (u8)s->m_cdvdman_command,
3505 s->m_read_chunk,
3506 s->m_read_callback) )
3507 {
3508 s->m_last_error = 0;
3509 return 1;
3510 }
3511 s->m_last_error = SCECdErREAD;
3512 }
3513 }
3514 }
3515 s->m_last_read_timeout = 0;
3516 switch ( s->m_recover_status )
3517 {
3518 case 1:
3519 s->m_sync_error = 0;
3520 s->m_interupt_read_state = 0;
3521 if (
3522 s->m_last_error
3523 || !sceCdRead0_Rty(
3524 s->m_dintrlsn,
3525 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
3526 s->m_read_buf,
3527 &s->m_read_mode,
3528 (u8)s->m_cdvdman_command,
3529 0,
3530 0) )
3531 {
3532 s->m_last_error = SCECdErREAD;
3533 s->m_recover_status = 0;
3534 }
3535 else
3536 {
3537 ext_passthrough = 1;
3538 }
3539 break;
3540 case 2:
3541 s->m_sync_error = 0;
3542 s->m_interupt_read_state = 0;
3543 if ( sceCdRead0(
3544 s->m_read_lsn, s->m_read_sectors, s->m_read_buf, &s->m_read_mode, s->m_read_chunk, s->m_read_callback) )
3545 {
3546 s->m_last_error = 0;
3547 s->m_recover_status = 3;
3548 return 1;
3549 }
3550 s->m_last_error = SCECdErREAD;
3551 s->m_recover_status = 0;
3552 break;
3553 case 3:
3554 s->m_recover_status = 0;
3555 break;
3556 default:
3557 break;
3558 }
3559 }
3560 if ( ext_passthrough )
3561 {
3562 s->m_last_error = 0;
3563 s->m_dintrlsn += s->m_read_sectors;
3564 s->m_read_chunk_reprocial_32 -= 1;
3565 s->m_recover_status = (!s->m_read_chunk_reprocial_32) ? 2 : 1;
3566 return 1;
3567 }
3568 if ( s->m_dec_state )
3569 {
3570 sceCdDecSet(0, 0, 0);
3571 }
3572 if ( (s->m_read2_flag == 1 || s->m_read2_flag == 3) && !s->m_use_toc )
3573 {
3574 VERBOSE_KPRINTF(1, "call Read2intrCDVD()\n");
3575 Read2intrCDVD(s->m_read2_flag);
3576 }
3577 s->m_sync_error = 0;
3578 s->m_interupt_read_state = 0;
3579 if ( s->m_dec_state == 2 )
3580 {
3581 s->m_dec_state = 0;
3582 }
3583 if ( s->m_stream_flag == 1 && !s->m_use_toc && !s->m_read2_flag )
3584 {
3585 if ( g_cdvdman_cdstm0cb )
3586 {
3587 g_cdvdman_cdstm0cb(1);
3588 }
3589 else
3590 {
3591 VERBOSE_KPRINTF(1, "Intr func0 no seting");
3592 }
3593 }
3594 if ( s->m_stream_flag == 2 && !s->m_use_toc )
3595 {
3596 if ( !s->m_read2_flag )
3597 {
3598 if ( g_cdvdman_cdstm1cb )
3599 {
3600 g_cdvdman_cdstm1cb(1);
3601 }
3602 else
3603 {
3604 VERBOSE_KPRINTF(1, "Intr func1 no seting");
3605 }
3606 }
3607 }
3608 else
3609 {
3610 if ( !s->m_read2_flag )
3611 {
3612 g_cdvdman_readptr = 0;
3613 }
3614 }
3615 VERBOSE_KPRINTF(
3616 1, "Intr call user callback func_addr %08x num %d flg %d\n", g_cdvdman_user_cb, g_cdvdman_cmdfunc, s->m_read2_flag);
3617 if ( g_cdvdman_user_cb && g_cdvdman_cmdfunc && !s->m_read2_flag && !s->m_use_toc )
3618 {
3619 int cmdfunc_tmp;
3620
3621 cmdfunc_tmp = g_cdvdman_cmdfunc;
3622 g_cdvdman_cmdfunc = 0;
3623 if ( cmdfunc_tmp == 14 || cmdfunc_tmp == 9 )
3624 {
3625 cmdfunc_tmp = SCECdFuncRead;
3626 }
3627 g_cdvdman_user_cb(cmdfunc_tmp);
3628 }
3629 if ( !g_cdvdman_user_cb )
3630 {
3631 g_cdvdman_cmdfunc = 0;
3632 }
3633 return 1;
3634}
3635
3636static int intrh_cdrom(cdvdman_internal_struct_t *s)
3637{
3638 int conds1;
3639 iop_event_info_t efinfo;
3640 USE_DEV5_MMIO_HWPORT();
3641
3642 conds1 = 0;
3643 s->m_waf_set_test = s->m_wait_flag;
3644 if ( (u8)s->m_last_error != 1 )
3645 {
3646 s->m_last_error = dev5_mmio_hwport->m_dev5_reg_006;
3647 }
3648 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
3649 {
3650 s->m_waf_set_test = (!(dev5_mmio_hwport->m_dev5_reg_005 & 1)) ? 1 : -1;
3651 dev5_mmio_hwport->m_dev5_reg_008 = 1;
3652 conds1 = 1;
3653 }
3654 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
3655 {
3656 dev5_mmio_hwport->m_dev5_reg_008 = 4;
3657 iSetEventFlag(g_cdvdman_intr_efid, 4);
3658 iSetEventFlag(g_cdvdman_intr_efid, 0x10);
3659 if ( g_cdvdman_poff_cb )
3660 {
3661 g_cdvdman_poff_cb(g_cdvdman_poffarg);
3662 }
3663 if ( !conds1 )
3664 {
3665 return 1;
3666 }
3667 }
3668 else
3669 {
3670 s->m_waf_set_test = 1;
3671 s->m_ncmd_intr_count += 1;
3672 dev5_mmio_hwport->m_dev5_reg_008 = 2;
3673 }
3674 iReferEventFlagStatus(g_cdvdman_intr_efid, &efinfo);
3675 if ( !(efinfo.currBits & 0x20) )
3676 {
3677 if ( !s->m_last_error )
3678 {
3679 s->m_drive_interupt_request = 1;
3680 return 1;
3681 }
3682 if ( s->m_last_error == SCECdErEOM )
3683 {
3684 intrh_dma_3(s);
3685 }
3686 }
3687 return cdvdman_intr_cb(s);
3688}
3689
3690static u32 cdvdman_l1start(const u8 *toc)
3691{
3692 return toc[23] + (toc[22] << 8) + (toc[21] << 16) - 0x30000 + 1;
3693}
3694
3695static int DvdDual_infochk()
3696{
3697 if ( QueryIntrContext() || !(cdvdman_mediactl(3) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
3698 {
3699 return 1;
3700 }
3701 g_cdvdman_istruct.m_use_toc = 1;
3702 if ( !cdvdman_gettoc(g_cdvdman_ptoc) )
3703 {
3704 g_cdvdman_istruct.m_use_toc = 0;
3705 g_cdvdman_istruct.m_opo_or_para = -1;
3706 return 0;
3707 }
3708 g_cdvdman_istruct.m_use_toc = 0;
3709 g_cdvdman_istruct.m_layer_1_lsn = cdvdman_l1start(g_cdvdman_ptoc);
3710 g_cdvdman_istruct.m_opo_or_para = ((g_cdvdman_ptoc[14] & 0x60)) ? (((g_cdvdman_ptoc[14] & 0x10)) ? 2 : 1) : 0;
3711 if ( g_cdvdman_istruct.m_dual_layer_emulation )
3712 {
3713 VERBOSE_KPRINTF(1, "CDVD:DualEmuON\n");
3714 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
3715 g_cdvdman_istruct.m_opo_or_para = 0;
3716 }
3717 VERBOSE_KPRINTF(
3718 1,
3719 "DvdDual_info: %02x\tLayer1_LSN:%d opo_or_para %d\n",
3720 g_cdvdman_ptoc[14],
3721 g_cdvdman_istruct.m_layer_1_lsn,
3722 (u8)g_cdvdman_istruct.m_opo_or_para);
3723 return 1;
3724}
3725
3726static u32 sceCdLsnDualChg(u32 lsn)
3727{
3728 int layer_disk_needed;
3729 u32 change_lsn;
3730 sceCdRMode cdrmode;
3731 int has_change_lsn;
3732
3733 layer_disk_needed = 2;
3734 has_change_lsn = 0;
3735 if ( cdvdman_isdvd() && DvdDual_infochk() )
3736 {
3737 if ( g_cdvdman_istruct.m_dual_layer_emulation )
3738 {
3739 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
3740 {
3741 layer_disk_needed = 1;
3742 }
3743 if ( g_cdvdman_istruct.m_current_dvd && lsn < g_cdvdman_istruct.m_current_dvd_lsn )
3744 {
3745 layer_disk_needed = 0;
3746 }
3747 if ( layer_disk_needed == 2 )
3748 {
3749 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
3750 has_change_lsn = 1;
3751 }
3752 else if ( !QueryIntrContext() )
3753 {
3754 u32 traychk;
3755
3756 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
3757 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
3758 {
3759 ;
3760 }
3761 cdrmode.trycount = 0;
3762 cdrmode.spindlctrl = SCECdSpinStm;
3763 cdrmode.datapattern = SCECdSecS2048;
3764 g_cdvdman_istruct.m_use_toc = 1;
3765 while ( layer_disk_needed != 2 )
3766 {
3767 if ( cdvdman_isdvd() )
3768 {
3769 int read0_result;
3770
3771 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
3772 sceCdSync(3);
3773 if ( !g_cdvdman_istruct.m_last_error || read0_result )
3774 {
3775 int i;
3776
3777 for ( i = 0; i < 20; i += 1 )
3778 {
3779 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
3780 {
3781 break;
3782 }
3783 }
3784 if ( i == 20 && g_cdvdman_ptoc[131] == 2 && (g_cdvdman_ptoc[132] & 2) )
3785 {
3786 if ( layer_disk_needed == g_cdvdman_ptoc[133] )
3787 {
3788 g_cdvdman_istruct.m_current_dvd = layer_disk_needed;
3789 layer_disk_needed = 2;
3790 }
3791 else
3792 {
3793 VERBOSE_KPRINTF(0, "CDVD: Layer_%d Disk not Found\n", layer_disk_needed);
3794 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
3795 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
3796 {
3797 layer_disk_needed = 1;
3798 }
3799 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
3800 {
3801 ;
3802 }
3803 }
3804 }
3805 else
3806 {
3807 VERBOSE_KPRINTF(0, "CDVD: Not Master Disk %s\n", (const char *)&g_cdvdman_ptoc[i + 104]);
3808 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
3809 {
3810 ;
3811 }
3812 }
3813 }
3814 else
3815 {
3816 VERBOSE_KPRINTF(1, "CDVD: LsnDualChg Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
3817 }
3818 }
3819 else
3820 {
3821 vDelayThread(16000);
3822 }
3823 }
3824 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
3825 g_cdvdman_istruct.m_use_toc = 0;
3826 has_change_lsn = 1;
3827 }
3828 }
3829 else
3830 {
3831 change_lsn =
3832 lsn - ((g_cdvdman_istruct.m_opo_or_para && (lsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn)) ? 0x10 : 0);
3833 has_change_lsn = 1;
3834 }
3835 }
3836 if ( has_change_lsn )
3837 {
3838 VERBOSE_KPRINTF(1, "CDVD: sceCdLsnDualChg lsn %d: change lsn %d\n", lsn, change_lsn);
3839 }
3840 return has_change_lsn ? change_lsn : lsn;
3841}
3842
3843int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
3844{
3845 int read0_result;
3846 int i;
3847 sceCdRMode cdrmode;
3848
3849 *on_dual = 0;
3850 *layer1_start = 0;
3851 g_cdvdman_istruct.m_dual_layer_emulation = 0;
3852 if ( !cdvdman_isdvd() )
3853 {
3854 return 1;
3855 }
3856 if ( !g_cdvdman_emudvd9 )
3857 {
3858 if ( !DvdDual_infochk() )
3859 {
3860 return 0;
3861 }
3862 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
3863 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
3864 return 1;
3865 }
3866 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
3867 {
3868 return 0;
3869 }
3870 cdrmode.trycount = 0;
3871 cdrmode.spindlctrl = SCECdSpinStm;
3872 cdrmode.datapattern = SCECdSecS2048;
3873 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
3874 sceCdSync(3);
3875 if ( g_cdvdman_istruct.m_last_error && !read0_result )
3876 {
3877 VERBOSE_KPRINTF(1, "CDVD: ReadDvdDualInfo Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
3878 return 0;
3879 }
3880 for ( i = 0; i < 20; i += 1 )
3881 {
3882 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
3883 {
3884 break;
3885 }
3886 }
3887 if ( i != 20 )
3888 {
3889 if ( !DvdDual_infochk() )
3890 {
3891 return 0;
3892 }
3893 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
3894 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
3895 return 1;
3896 }
3897 if ( g_cdvdman_ptoc[131] != 2 || !(g_cdvdman_ptoc[132] & 2) )
3898 {
3899 return 1;
3900 }
3901 g_cdvdman_istruct.m_current_dvd = g_cdvdman_ptoc[133];
3902 g_cdvdman_istruct.m_current_dvd_lsn =
3903 g_cdvdman_ptoc[134] + (g_cdvdman_ptoc[135] << 8) + (g_cdvdman_ptoc[136] << 16) + (g_cdvdman_ptoc[137] << 24) + 1;
3904 g_cdvdman_istruct.m_opo_or_para = 0;
3905 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
3906 g_cdvdman_istruct.m_dual_layer_emulation = 1;
3907 *on_dual = 1;
3908 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
3909 VERBOSE_KPRINTF(
3910 1,
3911 "sceCdReadDvdDualInfo():Cur_Disk %d layer1_start %d\n",
3912 (u8)g_cdvdman_istruct.m_current_dvd,
3913 g_cdvdman_istruct.m_current_dvd_lsn);
3914 return 1;
3915}
3916
3917int sceCdSC(int code, int *param)
3918{
3919 void *poffarg_tmp;
3920 int *BootMode;
3921 int state;
3922 u32 efbits;
3923
3924 switch ( code )
3925 {
3926 case 0xFFFFFFE6:
3927 CpuSuspendIntr(&state);
3928 *param = (int)g_cdvdman_poff_cb;
3929 poffarg_tmp = g_cdvdman_poffarg;
3930 CpuResumeIntr(state);
3931 return (int)poffarg_tmp;
3932 case 0xFFFFFFE7:
3933 return g_scmd_evid;
3934 case 0xFFFFFFE9:
3935 return sceCdLsnDualChg(*param);
3936 case 0xFFFFFFEA:
3937 return DvdDual_infochk();
3938 case 0xFFFFFFEE:
3939 g_cdvdman_istruct.m_last_read_timeout = *param;
3940 return 0;
3941 case 0xFFFFFFEF:
3942 return g_cdvdman_stream_timeout;
3943 case 0xFFFFFFF0:
3944 *param = (int)&g_verbose_level;
3945 return 0xFF;
3946 case 0xFFFFFFF1:
3947 return g_cdvdman_sync_timeout;
3948 case 0xFFFFFFF2:
3949 *param = (int)&g_cdvdman_istruct;
3950 return 0xFF;
3951 case 0xFFFFFFF3:
3952 BootMode = QueryBootMode(4);
3953 if ( BootMode )
3954 {
3955 switch ( *(u8 *)BootMode )
3956 {
3957 case 0:
3958 case 1:
3959 case 2:
3960 g_cdvdman_mmode = 0xFF;
3961 break;
3962 case 3:
3963 g_cdvdman_mmode = SCECdMmodeCd;
3964 break;
3965 }
3966 }
3967 return 1;
3968 case 0xFFFFFFF4:
3969 // The following call to sceCdGetDiskType was inlined
3970 switch ( sceCdGetDiskType() )
3971 {
3972 case SCECdPSCD:
3973 case SCECdPSCDDA:
3974 case SCECdPS2CD:
3975 case SCECdPS2CDDA:
3976 return g_cdvdman_mmode == SCECdMmodeCd || g_cdvdman_mmode == 0xFF;
3977 case SCECdPS2DVD:
3978 return g_cdvdman_mmode == SCECdMmodeDvd || g_cdvdman_mmode == 0xFF;
3979 case SCECdCDDA:
3980 return g_cdvdman_mmode == 0xFF;
3981 default:
3982 return 0;
3983 }
3984 case 0xFFFFFFF5:
3985 return g_cdvdman_intr_efid;
3986 case 0xFFFFFFF6:
3987 if ( *param )
3988 {
3989 WaitEventFlag(g_fio_fsv_evid, 1, WEF_AND | WEF_CLEAR, &efbits);
3990 }
3991 else
3992 {
3993 SetEventFlag(g_fio_fsv_evid, 1);
3994 }
3995 g_cdvdman_ee_rpc_fno = *param;
3996 VERBOSE_KPRINTF(1, "EE_ncmd_working code= %d\n", *param);
3997 return g_cdvdman_ee_rpc_fno;
3998 case 0xFFFFFFF7:
3999 return (u16)_irx_id.v;
4000 case 0xFFFFFFF8:
4001 g_cdvdman_spinctl = *param;
4002 return 1;
4003 case 0xFFFFFFFC:
4004 return g_cdvdman_cd36key;
4005 case 0xFFFFFFFD:
4006 return g_cdvdman_istruct.m_read2_flag;
4007 case 0xFFFFFFFE:
4008 g_cdvdman_istruct.m_last_error = *(u8 *)param;
4009 return (u8)g_cdvdman_istruct.m_last_error;
4010 case 0xFFFFFFFF:
4011 case 0:
4012 case 1:
4013 case 2:
4014 *param = (u8)g_cdvdman_istruct.m_last_error;
4015 if ( code != -1 )
4016 {
4017 g_cdvdman_istruct.m_stream_flag = code;
4018 }
4019 return g_cdvdman_istruct.m_stream_flag;
4020 default:
4021 VERBOSE_KPRINTF(1, "sceCdSC func_num Not found %d\n", code);
4022 return 0;
4023 }
4024}
4025
4026static void cdvdman_init()
4027{
4028 int *BootMode;
4029 unsigned int i;
4030 int scres_unused;
4031 u32 argres;
4032 USE_DEV5_MMIO_HWPORT();
4033
4034 g_cdvdman_user_cb = 0;
4035 g_cdvdman_poff_cb = 0;
4036 g_cdvdman_cmdfunc = 0;
4037 g_cdvdman_istruct.m_drive_interupt_request = 0;
4038 RegisterIntrHandler(IOP_IRQ_CDVD, 1, (int (*)(void *))intrh_cdrom, &g_cdvdman_istruct);
4039 RegisterIntrHandler(IOP_IRQ_DMA_CDVD, 1, (int (*)(void *))intrh_dma_3, &g_cdvdman_istruct);
4040 EnableIntr(IOP_IRQ_CDVD);
4041 sceCdSC(0xFFFFFFF3, &scres_unused);
4042 dmac_set_dpcr(dmac_get_dpcr() | 0x8000);
4043 dmac_ch_set_chcr(3, 0);
4044 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4045 {
4046 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4047 }
4048 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4049 {
4050 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4051 }
4052 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4053 g_cdvdman_istruct.m_tray_is_open = (dev5_mmio_hwport->m_dev5_reg_00A ^ 1) & 1;
4054 cdvdman_initcfg();
4055 BootMode = QueryBootMode(6);
4056 g_cdvdman_istruct.m_no_dec_flag = BootMode ? ((*(u16 *)BootMode & 0xFFFC) == 0x60) : 0;
4057 for ( i = 0; i <= 60 && (!sceCdCancelPOffRdy(&argres) || argres); i += 1 )
4058 {
4059 DelayThread(16000);
4060 }
4061}
4062
4063int sceCdInit(int mode)
4064{
4065 USE_DEV5_MMIO_HWPORT();
4066
4067 VERBOSE_PRINTF(1, "sceCdInit called mode= %d\n", mode);
4068 if ( mode == SCECdEXIT )
4069 {
4070 int oldstate;
4071
4072 g_cdvdman_istruct.m_cd_inited = 0;
4073 sceCdBreak();
4074 sceCdSync(3);
4075 cdvdman_ncmd_sender_06();
4076 sceCdSync(0);
4077 VERBOSE_PRINTF(1, "Cdvdman Exit\n");
4078 DisableIntr(IOP_IRQ_CDVD, &oldstate);
4079 ReleaseIntrHandler(IOP_IRQ_CDVD);
4080 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
4081 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
4082 }
4083 else
4084 {
4085 VERBOSE_PRINTF(1, "Cdvdman Init\n");
4086 g_cdvdman_istruct.m_read2_flag = 0;
4087 g_cdvdman_istruct.m_dec_shift = 0;
4088 g_cdvdman_istruct.m_check_version = 0;
4089 g_cdvdman_istruct.m_dec_state = 0;
4090 sceCdDecSet(0, 0, 0);
4091 cdvdman_init();
4092 g_cdvdman_istruct.m_cd_inited = 1;
4093 }
4094 if ( mode == SCECdINIT )
4095 {
4096 u8 ready_status_tmp;
4097 u8 ready_status;
4098 int ready_status_mask_c0h;
4099
4100 ready_status_tmp = 0;
4101 VERBOSE_PRINTF(1, "sceCdInit Ready check start.\n");
4102 for ( ready_status_mask_c0h = 0; ready_status_mask_c0h != 0x40; ready_status_mask_c0h = ready_status & 0xC0 )
4103 {
4104 ready_status = dev5_mmio_hwport->m_dev5_reg_005;
4105 vDelayThread(10000);
4106 if ( ready_status != ready_status_tmp )
4107 {
4108 ready_status_tmp = ready_status;
4109 VERBOSE_PRINTF(1, "sceCdInit Dev5 Status %x\n", ready_status);
4110 }
4111 }
4112 VERBOSE_PRINTF(1, "sceCdInit Ready check end.\n");
4113 }
4114 g_cdvdman_istruct.m_wait_flag = 1;
4115 g_cdvdman_istruct.m_scmd_flag = 1;
4116 g_cdvdman_istruct.m_last_error = 0;
4117 g_cdvdman_istruct.m_last_read_timeout = 0;
4118 g_cdvdman_spinctl = -1;
4119 SetEventFlag(g_cdvdman_intr_efid, 0x29);
4120 SetEventFlag(g_ncmd_evid, 1);
4121 SetEventFlag(g_scmd_evid, 1);
4122 SetEventFlag(g_sfile_evid, 1);
4123 return 1;
4124}
4125
4126static int set_prev_command(int cmd, const char *sdata, int sdlen, char *rdata, int rdlen, int check_sef)
4127{
4128 int i;
4129 int delaybackoff;
4130 int j;
4131 u32 efbits;
4132
4133 if ( check_sef == 1 && PollEventFlag(g_scmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4134 {
4135 return 0;
4136 }
4137 g_cdvdman_istruct.m_scmd = cmd;
4138 g_cdvdman_istruct.m_sdlen = sdlen;
4139 g_cdvdman_istruct.m_rdlen = rdlen;
4140 for ( i = 0; i < sdlen; i += 1 )
4141 {
4142 g_cdvdman_istruct.m_scmd_sd[i] = sdata[i];
4143 }
4144 if ( g_cdvdman_istruct.m_wait_flag )
4145 {
4146 g_cdvdman_istruct.m_scmd_flag = 1;
4147 cdvdman_write_scmd(&g_cdvdman_istruct);
4148 }
4149 else if ( QueryIntrContext() )
4150 {
4151 while ( (dmac_ch_get_chcr(3) & 0x1000000) && !g_cdvdman_istruct.m_wait_flag )
4152 {
4153 VERBOSE_KPRINTF(1, "set_prev_command: DMA Wait\n");
4154 }
4155 g_cdvdman_istruct.m_scmd_flag = 1;
4156 cdvdman_write_scmd(&g_cdvdman_istruct);
4157 }
4158 else
4159 {
4160 g_cdvdman_istruct.m_scmd_flag = 0;
4161 }
4162 delaybackoff = 1;
4163 for ( i = 0; i < 500; i += delaybackoff )
4164 {
4165 if ( g_cdvdman_istruct.m_scmd_flag )
4166 {
4167 for ( j = 0; j < rdlen; j += 1 )
4168 {
4169 rdata[j] = g_cdvdman_istruct.m_scmd_rd[j];
4170 }
4171 if ( check_sef == 1 )
4172 {
4173 vSetEventFlag(g_scmd_evid, 1);
4174 }
4175 return (u8)g_cdvdman_istruct.m_scmd;
4176 }
4177 vDelayThread(1000 * delaybackoff);
4178 if ( (i & 1) && delaybackoff < 16 )
4179 {
4180 delaybackoff *= 2;
4181 }
4182 }
4183 g_cdvdman_istruct.m_scmd_flag = 1;
4184 if ( check_sef == 1 )
4185 {
4186 vSetEventFlag(g_scmd_evid, 1);
4187 }
4188 return 0;
4189}
4190
4191static void cdvdman_write_scmd(cdvdman_internal_struct_t *s)
4192{
4193 int i;
4194 unsigned int j;
4195 unsigned int rdcnt;
4196 char rdptr1[64];
4197 USE_DEV5_MMIO_HWPORT();
4198
4199 for ( i = 0; i <= 0; i += 1 )
4200 {
4201 int overflowcond;
4202
4203 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
4204 {
4205 *(u16 *)&s->m_scmd_flag = 1;
4206 return;
4207 }
4208 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
4209 {
4210 ;
4211 }
4212 for ( j = 0; j < (u8)s->m_sdlen; j += 1 )
4213 {
4214 dev5_mmio_hwport->m_dev5_reg_017 = s->m_scmd_sd[j];
4215 }
4216 dev5_mmio_hwport->m_dev5_reg_016 = s->m_scmd;
4217 if ( QueryIntrContext() )
4218 {
4219 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
4220 {
4221 if ( j > 12500000 )
4222 {
4223 *(u16 *)&s->m_scmd_flag = 1;
4224 return;
4225 }
4226 }
4227 }
4228 else
4229 {
4230 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
4231 {
4232 DelayThread(100);
4233 if ( j > 50000 )
4234 {
4235 *(u16 *)&s->m_scmd_flag = 1;
4236 return;
4237 }
4238 }
4239 }
4240 overflowcond = 0;
4241 for ( j = 0; j < (u8)s->m_rdlen; j += 1 )
4242 {
4243 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
4244 {
4245 break;
4246 }
4247 rdptr1[j] = dev5_mmio_hwport->m_dev5_reg_018;
4248 }
4249 if ( j >= (u8)s->m_rdlen )
4250 {
4251 overflowcond = 1;
4252 VERBOSE_KPRINTF(1, "Prev Cmd Result Over Flow\n", rdptr1);
4253 }
4254 rdcnt = j;
4255 if ( (!overflowcond && j >= (u8)s->m_rdlen) || s->m_rdlen == 16 )
4256 {
4257 break;
4258 }
4259 VERBOSE_KPRINTF(1, "Prev Cmd Result Illegal Size Try count:%d\n", i);
4260 }
4261 if ( i == 1 )
4262 {
4263 *(u16 *)&s->m_scmd_flag = 1;
4264 }
4265 else
4266 {
4267 for ( j = 0; j < (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])); j += 1 )
4268 {
4269 s->m_scmd_rd[j] = 0;
4270 }
4271 if ( s->m_rdlen != (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])) )
4272 {
4273 rdcnt = (u8)s->m_rdlen;
4274 }
4275 for ( j = 0; j < rdcnt; j += 1 )
4276 {
4277 s->m_scmd_rd[j] = rdptr1[j];
4278 }
4279 s->m_scmd_flag = 1;
4280 s->m_scmd = 1;
4281 }
4282}
4283
4284static int cdvdman_send_scmd2(int cmd, const void *sdata, int sdlen, void *rdata, int rdlen, int check_sef)
4285{
4286 int i;
4287 int j;
4288 char rdstart[64];
4289 u32 efbits;
4290 USE_DEV5_MMIO_HWPORT();
4291
4292 if ( check_sef == 1 && PollEventFlag(g_scmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4293 {
4294 return 0;
4295 }
4296 for ( i = 0; i <= 0; i += 1 )
4297 {
4298 int cmdresoverflow;
4299
4300 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
4301 {
4302 if ( check_sef == 1 )
4303 {
4304 vSetEventFlag(g_scmd_evid, 1);
4305 }
4306 return 0;
4307 }
4308 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
4309 {
4310 ;
4311 }
4312 for ( j = 0; j < sdlen; j += 1 )
4313 {
4314 dev5_mmio_hwport->m_dev5_reg_017 = ((u8 *)sdata)[j];
4315 }
4316 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
4317 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
4318 {
4319 DelayThread(100);
4320 }
4321 cmdresoverflow = 0;
4322 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
4323 {
4324 if ( j >= rdlen )
4325 {
4326 cmdresoverflow = 1;
4327 VERBOSE_KPRINTF(1, "Prev Cmd Result Over Flow\n");
4328 break;
4329 }
4330 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
4331 }
4332 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
4333 {
4334 break;
4335 }
4336 VERBOSE_KPRINTF(1, "Prev Cmd Result Illegal Size Try count:%d\n", i);
4337 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
4338 {
4339 ;
4340 }
4341 for ( j = 0; j < 16 - rdlen; j += 1 )
4342 ;
4343 }
4344 if ( i == 1 )
4345 {
4346 if ( check_sef == 1 )
4347 {
4348 vSetEventFlag(g_scmd_evid, 1);
4349 }
4350 return 0;
4351 }
4352 for ( i = 0; i < rdlen; i += 1 )
4353 {
4354 ((char *)rdata)[i] = rdstart[i];
4355 }
4356 if ( check_sef == 1 )
4357 {
4358 vSetEventFlag(g_scmd_evid, 1);
4359 }
4360 return 1;
4361}
4362
4363int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
4364{
4365 int i;
4366
4367 for ( i = 0; i <= 2500; i += 1 )
4368 {
4369 if ( set_prev_command(cmdNum, (const char *)inBuff, inBuffSize, (char *)outBuff, 16, 1) )
4370 {
4371 DelayThread(2000);
4372 return 1;
4373 }
4374 DelayThread(2000);
4375 }
4376 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
4377 return 0;
4378}
4379
4380int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
4381{
4382 int i;
4383
4384 for ( i = 0; i <= 2500; i += 1 )
4385 {
4386 if ( cdvdman_send_scmd2(cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
4387 {
4388 return 1;
4389 }
4390 DelayThread(2000);
4391 }
4392 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
4393 return 0;
4394}
4395
4396#ifdef DEAD_CODE
4397int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
4398{
4399 int i;
4400
4401 for ( i = 0; i <= 2500; i += 1 )
4402 {
4403 DelayThread(2000);
4404 if ( set_prev_command((u8)cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
4405 {
4406 DelayThread(2000);
4407 return 1;
4408 }
4409 }
4410 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
4411 return 0;
4412}
4413#endif
4414
4415int sceCdBreak(void)
4416{
4417 u32 efbits;
4418 int state;
4419 int oldstate;
4420 USE_DEV5_MMIO_HWPORT();
4421
4422 if ( PollEventFlag(g_ncmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4423 {
4424 return 0;
4425 }
4426 CpuSuspendIntr(&state);
4427 VERBOSE_KPRINTF(
4428 1,
4429 "Break call: read2_flg= %d func= %d lsn= %d csec= %d nsec= %d\n",
4430 g_cdvdman_istruct.m_read2_flag,
4431 g_cdvdman_cmdfunc,
4432 g_cdvdman_istruct.m_cdvdman_lsn,
4433 g_cdvdman_istruct.m_cdvdman_csec,
4434 g_cdvdman_istruct.m_cdvdman_nsec);
4435 if ( g_cdvdman_istruct.m_last_read_timeout )
4436 {
4437 g_cdvdman_istruct.m_read2_flag = 0;
4438 }
4439 g_cdvdman_istruct.m_last_error = SCECdErABRT;
4440 g_cdvdman_istruct.m_thread_id = GetThreadId();
4441 g_cdvdman_istruct.m_break_cdvdfsv_readchain = 1;
4442 if ( g_cdvdman_istruct.m_dec_state )
4443 {
4444 g_cdvdman_istruct.m_dec_shift = 0;
4445 g_cdvdman_istruct.m_check_version = 0;
4446 g_cdvdman_istruct.m_dec_state = 0;
4447 sceCdDecSet(0, 0, 0);
4448 }
4449 g_cdvdman_istruct.m_recover_status = 0;
4450 if ( QueryIntrContext() )
4451 {
4452 iSetEventFlag(g_cdvdman_intr_efid, 0x29);
4453 iCancelAlarm((unsigned int (*)(void *))read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
4454 }
4455 else
4456 {
4457 SetEventFlag(g_cdvdman_intr_efid, 0x29);
4458 CancelAlarm((unsigned int (*)(void *))read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
4459 }
4460 if ( !g_cdvdman_istruct.m_wait_flag || g_cdvdman_istruct.m_last_read_timeout )
4461 {
4462 if ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) == 0x40 )
4463 {
4464 VERBOSE_KPRINTF(1, "cdvd: NonInter END\n");
4465 g_cdvdman_istruct.m_wait_flag = 1;
4466 }
4467 g_cdvdman_last_cmdfunc = g_cdvdman_cmdfunc;
4468 g_cdvdman_cmdfunc = SCECdFuncBreak;
4469 dev5_mmio_hwport->m_dev5_reg_007 = 1;
4470 if ( g_cdvdman_istruct.m_last_read_timeout )
4471 {
4472 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
4473 }
4474 g_cdvdman_istruct.m_drive_interupt_request = 0;
4475 VERBOSE_KPRINTF(1, "cdvd: Abort command On\n");
4476 }
4477 vSetEventFlag(g_ncmd_evid, 1);
4478 CpuResumeIntr(state);
4479 return 1;
4480}
4481
4482static int ncmd_timeout_alarm_cb(iop_sys_clock_t *sys_clock)
4483{
4484 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
4485 sys_clock->lo = 0;
4486 return 0;
4487}
4488
4489static int intrh_dma_3(cdvdman_internal_struct_t *s)
4490{
4491 int dmacbres;
4492 int oldstate;
4493
4494 s->m_dma3_param.m_dma3_msectors -= s->m_dma3_param.m_dma3_csectors;
4495 dmacbres = s->m_dma3_param.m_dma3_callback ? s->m_dma3_param.m_dma3_callback() : 1;
4496 s->m_cdvdman_dma3sec += s->m_dma3_param.m_dma3_csectors;
4497 s->m_dma3_param.m_dma3_csectors = ((u32)s->m_read_chunk > (u32)s->m_dma3_param.m_dma3_msectors) ?
4498 (u32)s->m_dma3_param.m_dma3_msectors :
4499 (u32)s->m_read_chunk;
4500 if ( dmacbres )
4501 {
4502 if ( s->m_dma3_param.m_dma3_msectors )
4503 {
4504 dmac_ch_set_chcr(3, 0);
4505 dmac_ch_get_chcr(3);
4506 dmac_ch_set_madr(3, (u32)s->m_dma3_param.m_dma3_maddress);
4507 dmac_ch_set_bcr(
4508 3,
4509 ((s->m_dma3_param.m_dma3_blkcount * s->m_dma3_param.m_dma3_csectors) << 16) | s->m_dma3_param.m_dma3_blkwords);
4510 dmac_ch_set_chcr(3, 0x41000200);
4511 dmac_ch_get_chcr(3);
4512 iClearEventFlag(g_cdvdman_intr_efid, ~0x20);
4513 }
4514 else
4515 {
4516 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
4517 iSetEventFlag(g_cdvdman_intr_efid, 0x20);
4518 }
4519 }
4520 if ( !s->m_dma3_param.m_dma3_msectors && s->m_drive_interupt_request )
4521 {
4522 cdvdman_intr_cb(s);
4523 s->m_drive_interupt_request = 0;
4524 }
4525 return 1;
4526}
4527
4528static int cdvdman_setdma3(cdvdman_dma3_parameter_t *dma3_param)
4529{
4530 USE_DEV5_MMIO_HWPORT();
4531
4532 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
4533 {
4534 dev5_mmio_hwport->m_dev5_reg_007 = 1;
4535 }
4536 g_cdvdman_istruct.m_drive_interupt_request = 0;
4537 g_cdvdman_istruct.m_dma3_param.m_dma3_blkwords = dma3_param->m_dma3_blkwords;
4538 g_cdvdman_istruct.m_dma3_param.m_dma3_blkcount = dma3_param->m_dma3_blkcount;
4539 g_cdvdman_istruct.m_dma3_param.m_dma3_maddress = dma3_param->m_dma3_maddress;
4540 g_cdvdman_istruct.m_dma3_param.m_dma3_callback = dma3_param->m_dma3_callback;
4541 g_cdvdman_istruct.m_dma3_param.m_dma3_csectors = dma3_param->m_dma3_csectors;
4542 g_cdvdman_istruct.m_dma3_param.m_cdvdreg_howto = dma3_param->m_cdvdreg_howto;
4543 g_cdvdman_istruct.m_dma3_param.m_dma3_msectors = dma3_param->m_dma3_msectors;
4544 g_cdvdman_istruct.m_cdvdman_dma3sec = 0;
4545 dmac_ch_set_chcr(3, 0);
4546 dmac_ch_get_chcr(3);
4547 if ( dma3_param->m_dma3_csectors )
4548 {
4549 vClearEventFlag(g_cdvdman_intr_efid, ~0x20);
4550 EnableIntr(IOP_IRQ_DMA_CDVD);
4551 }
4552 dev5_mmio_hwport->m_dev5_reg_006 = dma3_param->m_cdvdreg_howto;
4553 dmac_ch_set_madr(3, (u32)dma3_param->m_dma3_maddress);
4554 dmac_ch_set_bcr(
4555 3,
4556 (dma3_param->m_dma3_blkcount * (dma3_param->m_dma3_csectors ? dma3_param->m_dma3_csectors : 1)) << 16
4557 | dma3_param->m_dma3_blkwords);
4558 dmac_ch_set_chcr(3, 0x41000200);
4559 return dmac_ch_get_chcr(3);
4560}
4561
4562static int
4563cdvdman_send_ncmd(int ncmd, const void *ndata, int ndlen, int func, cdvdman_dma3_parameter_t *dma3_param, int check_cb)
4564{
4565 int i;
4566 u32 efbits;
4567 USE_DEV5_MMIO_HWPORT();
4568
4569 if ( check_cb == 1 && PollEventFlag(g_ncmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4570 {
4571 return -1;
4572 }
4573 if (
4574 (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) != 0x40 || !g_cdvdman_istruct.m_wait_flag
4575 || !(g_cdvdman_istruct.m_read2_flag != 1 || ncmd == 8) || !(g_cdvdman_istruct.m_read2_flag != 2 || ncmd == 6) )
4576 {
4577 if ( check_cb == 1 )
4578 {
4579 vSetEventFlag(g_ncmd_evid, 1);
4580 }
4581 VERBOSE_KPRINTF(1, "set_cd_commnad Error\tstat %02x\n", (u8)dev5_mmio_hwport->m_dev5_reg_005);
4582 return -1;
4583 }
4584 g_cdvdman_iocache = 0;
4585 if ( dma3_param )
4586 {
4587 cdvdman_setdma3(dma3_param);
4588 }
4589 g_cdvdman_cmdfunc = func;
4590 // The following call to sceCdGetDiskType was inlined
4591 if (
4592 !g_cdvdman_minver_10700 && g_cdvdman_ncmd == 6 && ncmd && ncmd != g_cdvdman_ncmd && ncmd != 7 && ncmd != 14
4593 && ncmd != 8 && (sceCdGetDiskType() != SCECdCDDA || ncmd == 3) )
4594 {
4595 g_cdvdman_ncmd_timeout.hi = 0;
4596 g_cdvdman_ncmd_timeout.lo = 0x6978000;
4597 vSetAlarm(&g_cdvdman_ncmd_timeout, (unsigned int (*)(void *))ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
4598 while ( dev5_mmio_hwport->m_dev5_reg_00A != 10 )
4599 {
4600 VERBOSE_KPRINTF(1, "Read Pause 1 chk status 0x%02x\n", dev5_mmio_hwport->m_dev5_reg_00A);
4601 if ( !g_cdvdman_ncmd_timeout.lo )
4602 {
4603 g_cdvdman_ncmd = ncmd;
4604 if ( check_cb == 1 )
4605 {
4606 vSetEventFlag(g_ncmd_evid, 1);
4607 }
4608 KPRINTF("Time Out Pause WAIT set_cd_commnad\n");
4609 return -1;
4610 }
4611 vDelayThread(1000);
4612 }
4613 vCancelAlarm((unsigned int (*)(void *))ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
4614 }
4615 g_cdvdman_ncmd = ncmd;
4616 if ( g_cdvdman_istruct.m_dec_state )
4617 {
4618 sceCdDecSet(!!g_cdvdman_istruct.m_dec_shift, 1, g_cdvdman_istruct.m_dec_shift);
4619 }
4620 g_cdvdman_istruct.m_last_read_timeout = 0;
4621 g_cdvdman_istruct.m_cdvdman_command = ncmd;
4622 g_cdvdman_istruct.m_last_error = 0;
4623 g_cdvdman_istruct.m_wait_flag = 0;
4624 g_cdvdman_istruct.m_thread_id = GetThreadId();
4625 if ( QueryIntrContext() )
4626 {
4627 iClearEventFlag(g_cdvdman_intr_efid, ~1);
4628 }
4629 else
4630 {
4631 ClearEventFlag(g_cdvdman_intr_efid, ~1);
4632 }
4633 for ( i = 0; i < ndlen; i += 1 )
4634 {
4635 dev5_mmio_hwport->m_dev5_reg_005 = ((u8 *)ndata)[i];
4636 }
4637 dev5_mmio_hwport->m_dev5_reg_004 = ncmd;
4638 if ( check_cb == 1 )
4639 {
4640 vSetEventFlag(g_ncmd_evid, 1);
4641 }
4642 return 0;
4643}
4644
4645int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
4646{
4647 VERBOSE_KPRINTF(1, "Apply NCmd call cmd= 0x%02x\n", cmdNum);
4648 while ( cdvdman_send_ncmd(cmdNum, inBuff, inBuffSize, 0, 0, 1) < 0 )
4649 {
4650 vDelayThread(2000);
4651 }
4652 sceCdSync(4);
4653 return 1;
4654}
4655
4656int sceCdCheckCmd(void)
4657{
4658 return g_cdvdman_istruct.m_wait_flag;
4659}
4660
4661static int cdvdman_mediactl(int code)
4662{
4663 int reg_00B_tmp_1;
4664 int restmp;
4665 u32 efbits;
4666 int rdata;
4667 USE_DEV5_MMIO_HWPORT();
4668
4669 rdata = 0;
4670 if ( PollEventFlag(g_scmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4671 {
4672 return 0;
4673 }
4674 reg_00B_tmp_1 = dev5_mmio_hwport->m_dev5_reg_00B & 1;
4675 if ( reg_00B_tmp_1 == g_cdvdman_chmedia )
4676 {
4677 restmp = 0;
4678 if ( g_cdvdman_chflags[code] )
4679 {
4680 g_cdvdman_chflags[code] = 0;
4681 restmp = 1;
4682 }
4683 }
4684 else
4685 {
4686 unsigned int i;
4687
4688 for ( i = 0; i < (sizeof(g_cdvdman_chflags) / sizeof(g_cdvdman_chflags[0])); i += 1 )
4689 {
4690 g_cdvdman_chflags[i] = i != (unsigned int)code;
4691 }
4692 restmp = 1;
4693 }
4694 if ( ((dev5_mmio_hwport->m_dev5_reg_00A) & 1) != reg_00B_tmp_1 )
4695 {
4696 while ( !set_prev_command(5, 0, 0, (char *)&rdata, 1, 0) || rdata )
4697 {
4698 vDelayThread(4000);
4699 }
4700 }
4701 g_cdvdman_chmedia = dev5_mmio_hwport->m_dev5_reg_00B & 1;
4702 vSetEventFlag(g_scmd_evid, 1);
4703 return restmp;
4704}
4705
4706int sceCdGetError(void)
4707{
4708 if ( g_cdvdman_istruct.m_last_error )
4709 {
4710 VERBOSE_KPRINTF(1, "sceCdGetError: 0x%02x\n", (u8)g_cdvdman_istruct.m_last_error);
4711 }
4712 return (u8)g_cdvdman_istruct.m_last_error;
4713}
4714
4715#ifdef DEAD_CODE
4716int cdvdman_get_last_command()
4717{
4718 return (u8)g_cdvdman_istruct.m_cdvdman_command;
4719}
4720#endif
4721
4722int sceCdNop(void)
4723{
4724 return cdvdman_send_ncmd(0, 0, 0, 0, 0, 1) >= 0;
4725}
4726
4727#ifdef DEAD_CODE
4728int cdvdman_ncmd_sender_01()
4729{
4730 return cdvdman_send_ncmd(1, 0, 0, 0, 0, 1) >= 0;
4731}
4732#endif
4733
4734static int cdvdman_ncmd_sender_06()
4735{
4736 int i;
4737 cdvdman_dma3_parameter_t dma3_param;
4738 char ndata[11];
4739
4740 // The following call to sceCdGetDiskType was inlined
4741 if ( sceCdGetDiskType() == SCECdNODISC )
4742 {
4743 return 1;
4744 }
4745 for ( i = 0; i < 48; i += 8 )
4746 {
4747 KPRINTF("CMD_READP call\n");
4748 ndata[0] = i + 17;
4749 ndata[3] = 0;
4750 ndata[2] = 0;
4751 ndata[1] = 0;
4752 ndata[4] = 8;
4753 ndata[7] = 0;
4754 ndata[6] = 0;
4755 ndata[5] = 0;
4756 ndata[8] = 0;
4757 ndata[9] = 1;
4758 ndata[10] = 0;
4759 dma3_param.m_cdvdreg_howto = 128;
4760 dma3_param.m_dma3_blkwords = 32;
4761 dma3_param.m_dma3_blkcount = 128;
4762 dma3_param.m_dma3_csectors = 0;
4763 dma3_param.m_dma3_msectors = 0;
4764 dma3_param.m_dma3_callback = 0;
4765 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
4766 if ( cdvdman_send_ncmd(6, ndata, sizeof(ndata), 5, &dma3_param, 1) < 0 )
4767 {
4768 return 0;
4769 }
4770 sceCdSync(3);
4771 }
4772 return 1;
4773}
4774
4775int sceCdStandby(void)
4776{
4777 cdvdman_dma3_parameter_t dma3_param;
4778 char ndata[11];
4779
4780 // The following call to sceCdGetDiskType was inlined
4781 switch ( sceCdGetDiskType() )
4782 {
4783 case SCECdPSCD:
4784 case SCECdPSCDDA:
4785 case SCECdPS2CD:
4786 case SCECdPS2CDDA:
4787 case SCECdPS2DVD:
4788 ndata[0] = 16;
4789 ndata[4] = 1;
4790 ndata[9] = 1;
4791 dma3_param.m_cdvdreg_howto = 128;
4792 dma3_param.m_dma3_blkwords = 32;
4793 dma3_param.m_dma3_blkcount = 16;
4794 ndata[3] = 0;
4795 ndata[2] = 0;
4796 ndata[1] = 0;
4797 ndata[7] = 0;
4798 ndata[6] = 0;
4799 ndata[5] = 0;
4800 ndata[8] = 0;
4801 ndata[10] = 0;
4802 dma3_param.m_dma3_csectors = 0;
4803 dma3_param.m_dma3_msectors = 0;
4804 dma3_param.m_dma3_callback = 0;
4805 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
4806 return cdvdman_send_ncmd(6, ndata, sizeof(ndata), 5, &dma3_param, 1) >= 0;
4807 default:
4808 return cdvdman_send_ncmd(2, 0, 0, 5, 0, 1) >= 0;
4809 }
4810}
4811
4812int sceCdStop(void)
4813{
4814 return cdvdman_send_ncmd(3, 0, 0, 6, 0, 1) >= 0;
4815}
4816
4817int sceCdPause(void)
4818{
4819 return cdvdman_send_ncmd(4, 0, 0, 7, 0, 1) >= 0;
4820}
4821
4822#ifdef DEAD_CODE
4823int cdvdman_ncmd_sender_0B()
4824{
4825 char ndata;
4826
4827 ndata = 1;
4828 return cdvdman_send_ncmd(11, &ndata, sizeof(ndata), 0, 0, 1) >= 0;
4829}
4830#endif
4831
4832static int readtoc_timeout_alarm_cb(iop_sys_clock_t *sys_clock)
4833{
4834 USE_DEV5_MMIO_HWPORT();
4835
4836 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
4837 dev5_mmio_hwport->m_dev5_reg_007 = 1;
4838 sys_clock->lo = 0;
4839 return 0;
4840}
4841
4842static int cdvdman_readtoc(u8 *toc, int param, int func)
4843{
4844 int errcond;
4845 cdvdman_dma3_parameter_t dma3_param;
4846 iop_sys_clock_t sysclk;
4847 char ndata;
4848
4849 // The following call to sceCdGetDiskType was inlined
4850 switch ( sceCdGetDiskType() )
4851 {
4852 case SCECdPS2DVD:
4853 case SCECdDVDVR:
4854 case SCECdDVDV:
4855 dma3_param.m_cdvdreg_howto = 132;
4856 dma3_param.m_dma3_blkwords = 4;
4857 dma3_param.m_dma3_blkcount = 129;
4858 dma3_param.m_dma3_maddress = toc;
4859 dma3_param.m_dma3_msectors = 0;
4860 dma3_param.m_dma3_csectors = 0;
4861 dma3_param.m_dma3_callback = 0;
4862 ndata = param;
4863 break;
4864 case SCECdPSCD:
4865 case SCECdPSCDDA:
4866 case SCECdPS2CD:
4867 case SCECdPS2CDDA:
4868 dma3_param.m_cdvdreg_howto = 128;
4869 dma3_param.m_dma3_blkwords = 32;
4870 dma3_param.m_dma3_blkcount = 8;
4871 dma3_param.m_dma3_maddress = toc;
4872 dma3_param.m_dma3_msectors = 0;
4873 dma3_param.m_dma3_csectors = 0;
4874 dma3_param.m_dma3_callback = 0;
4875 ndata = 0;
4876 break;
4877 case 0xFD:
4878 break;
4879 default:
4880 return 0;
4881 }
4882 if ( cdvdman_send_ncmd(9, &ndata, sizeof(ndata), func, &dma3_param, 1) < 0 )
4883 {
4884 return 0;
4885 }
4886 sysclk.hi = 0;
4887 sysclk.lo = 0x15F90000;
4888 vSetAlarm(&sysclk, (unsigned int (*)(void *))readtoc_timeout_alarm_cb, &sysclk);
4889 sceCdSync(3);
4890 vCancelAlarm((unsigned int (*)(void *))readtoc_timeout_alarm_cb, &sysclk);
4891 errcond = !sceCdGetError();
4892 if ( g_cdvdman_minver_10700 && !sceCdPause() )
4893 {
4894 return 0;
4895 }
4896 sceCdSync(3);
4897 return errcond;
4898}
4899
4900static int cdvdman_gettoc(u8 *toc)
4901{
4902 return cdvdman_readtoc(toc, 0, 3);
4903}
4904
4905u32 sceCdGetReadPos(void)
4906{
4907 int sector_sizes[4];
4908
4909 sector_sizes[0] = 0x800;
4910 sector_sizes[1] = 0x918;
4911 sector_sizes[2] = 0x924;
4912 if ( g_cdvdman_istruct.m_recover_status && g_cdvdman_istruct.m_recover_status != 3 )
4913 {
4914 return 0;
4915 }
4916 if ( g_cdvdman_cmdfunc == SCECdFuncReadCDDA || g_cdvdman_cmdfunc == 12 )
4917 {
4918 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
4919 }
4920 if ( g_cdvdman_istruct.m_read2_flag )
4921 {
4922 return g_cdvdman_readptr * sector_sizes[g_cdvdman_istruct.m_cdvdman_pattern];
4923 }
4924 if ( g_cdvdman_cmdfunc == SCECdFuncRead )
4925 {
4926 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
4927 }
4928 return 0;
4929}
4930
4931static int cdvdman_speedctl(u32 spindlctrl, int dvdflag, u32 maxlsn)
4932{
4933 u32 maxlsn_chk;
4934
4935 switch ( spindlctrl )
4936 {
4937 case SCECdSpinStm:
4938 return dvdflag ? 2 : 4;
4939 case SCECdSpinNom:
4940 if ( !dvdflag )
4941 {
4942 return 133;
4943 }
4944 if ( g_cdvdman_minver_10700 )
4945 {
4946 return 131;
4947 }
4948 maxlsn_chk = 0x128000;
4949 if ( g_cdvdman_istruct.m_opo_or_para )
4950 {
4951 maxlsn -= (maxlsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn) ? g_cdvdman_istruct.m_layer_1_lsn : 0;
4952 maxlsn_chk = 0x165000;
4953 }
4954 if ( maxlsn >= maxlsn_chk )
4955 {
4956 VERBOSE_KPRINTF(1, "Kprob Spd D lsn= %d\n", maxlsn);
4957 return 130;
4958 }
4959 return 133;
4960 case SCECdSpinX1:
4961 case 0xE:
4962 return 1;
4963 case SCECdSpinX2:
4964 return 2;
4965 case SCECdSpinX4:
4966 return dvdflag ? 2 : 131;
4967 case SCECdSpinX12:
4968 return dvdflag ? 3 : 4;
4969 case SCECdSpinNm2:
4970 return 64;
4971 case 0xC:
4972 return dvdflag ? 4 : 2;
4973 case 0xF:
4974 return 130;
4975 case 0x10:
4976 return dvdflag ? 130 : 131;
4977 case 0x11:
4978 return dvdflag ? 130 : 132;
4979 case 0x12:
4980 return dvdflag ? 1 : 131;
4981 case SCECdSpinMx:
4982 return dvdflag ? 3 : 5;
4983 default:
4984 return dvdflag ? 131 : 133;
4985 }
4986}
4987
4988static int cdvdman_isdvd()
4989{
4990 // The following call to sceCdGetDiskType was inlined
4991 switch ( sceCdGetDiskType() )
4992 {
4993 case SCECdPSCD:
4994 case SCECdPSCDDA:
4995 case SCECdPS2CD:
4996 case SCECdPS2CDDA:
4997 g_cdvdman_istruct.m_tray_is_open = 1;
4998 return 0;
4999 case SCECdPS2DVD:
5000 g_cdvdman_istruct.m_tray_is_open = 1;
5001 return 1;
5002 case SCECdDVDVR:
5003 case SCECdDVDV:
5004 g_cdvdman_istruct.m_tray_is_open = 1;
5005 return 1;
5006 case SCECdCDDA:
5007 g_cdvdman_istruct.m_tray_is_open = 1;
5008 return 0;
5009 default:
5010 return 0;
5011 }
5012}
5013
5014static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func)
5015{
5016 cdvdman_dma3_parameter_t dma3_param;
5017 char ndata[11];
5018
5019 g_cdvdman_readbuf = buf;
5020 VERBOSE_KPRINTF(1, "sceCdRead0_Rty Lsn:%d nsec:%d dintrnsec %d func %08x\n", lsn, nsec, dintrsec, func);
5021 *(u32 *)ndata = lsn;
5022 *(u32 *)&ndata[4] = nsec;
5023 ndata[8] = mode->trycount;
5024 ndata[9] = cdvdman_speedctl(mode->spindlctrl, cdvdman_isdvd(), lsn + nsec);
5025 dma3_param.m_dma3_csectors = dintrsec;
5026 dma3_param.m_dma3_callback = (int (*)(void))func;
5027 dma3_param.m_dma3_msectors = nsec;
5028 dma3_param.m_dma3_maddress = buf;
5029 dma3_param.m_dma3_blkcount = (!(u16)dintrsec) ? nsec : 1;
5030 if ( ncmd == 6 )
5031 {
5032 ndata[10] = mode->datapattern;
5033 switch ( mode->datapattern )
5034 {
5035 case 1:
5036 dma3_param.m_dma3_blkwords = 6;
5037 dma3_param.m_dma3_blkcount *= 97;
5038 dma3_param.m_cdvdreg_howto = 134;
5039 break;
5040 case 2:
5041 dma3_param.m_dma3_blkwords = 15;
5042 dma3_param.m_dma3_blkcount *= 39;
5043 dma3_param.m_cdvdreg_howto = 143;
5044 break;
5045 case 0:
5046 default:
5047 dma3_param.m_dma3_blkwords = 32;
5048 dma3_param.m_dma3_blkcount *= 16;
5049 dma3_param.m_cdvdreg_howto = 128;
5050 break;
5051 }
5052 if ( cdvdman_send_ncmd(ncmd, ndata, sizeof(ndata), 1, &dma3_param, 0) >= 0 )
5053 {
5054 return 1;
5055 }
5056 }
5057 if ( ncmd == 8 )
5058 {
5059 dma3_param.m_dma3_blkwords = 12;
5060 dma3_param.m_dma3_blkcount *= 43;
5061 dma3_param.m_cdvdreg_howto = 140;
5062 ndata[10] = 0;
5063 if ( cdvdman_send_ncmd(ncmd, ndata, sizeof(ndata), 14, &dma3_param, 0) >= 0 )
5064 {
5065 return 1;
5066 }
5067 }
5068 return 0;
5069}
5070
5071int sceCdRead0(u32 lsn, u32 sectors, void *buffer, sceCdRMode *mode, int csec, void *callback)
5072{
5073 cdvdman_dma3_parameter_t dma3_param;
5074 char ndata[11];
5075 u32 efbits;
5076
5077 if ( PollEventFlag(g_ncmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5078 {
5079 return 0;
5080 }
5081 VERBOSE_KPRINTF(
5082 1,
5083 "DVD/CD sceCdRead0 sec %d num %d spin %d trycnt %d dptn %d adr %08x\n",
5084 lsn,
5085 sectors,
5086 mode->spindlctrl,
5087 mode->trycount,
5088 mode->datapattern,
5089 buffer);
5090 g_cdvdman_readbuf = buffer;
5091 dma3_param.m_dma3_csectors = (csec && (sectors < (u32)csec)) ? sectors : (u32)csec;
5092 dma3_param.m_dma3_callback = (int (*)(void))callback;
5093 dma3_param.m_dma3_msectors = sectors;
5094 dma3_param.m_dma3_blkcount = (!csec) ? sectors : 1;
5095 switch ( mode->datapattern )
5096 {
5097 case SCECdSecS2328:
5098 dma3_param.m_dma3_blkwords = 6;
5099 dma3_param.m_dma3_blkcount *= 97;
5100 dma3_param.m_cdvdreg_howto = 134;
5101 break;
5102 case SCECdSecS2340:
5103 dma3_param.m_dma3_blkwords = 15;
5104 dma3_param.m_dma3_blkcount *= 39;
5105 dma3_param.m_cdvdreg_howto = 143;
5106 break;
5107 case SCECdSecS2048:
5108 default:
5109 dma3_param.m_dma3_blkwords = 32;
5110 dma3_param.m_dma3_blkcount *= 16;
5111 dma3_param.m_cdvdreg_howto = 128;
5112 break;
5113 }
5114 // The following call to sceCdGetDiskType was inlined
5115 switch ( sceCdGetDiskType() )
5116 {
5117 case SCECdPSCD:
5118 case SCECdPSCDDA:
5119 case SCECdPS2CD:
5120 case SCECdPS2CDDA:
5121 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
5122 {
5123 vSetEventFlag(g_ncmd_evid, 1);
5124 return 0;
5125 }
5126 g_cdvdman_istruct.m_dvd_flag = 0;
5127 break;
5128 case SCECdPS2DVD:
5129 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
5130 {
5131 vSetEventFlag(g_ncmd_evid, 1);
5132 return 0;
5133 }
5134 g_cdvdman_istruct.m_dvd_flag = 1;
5135 break;
5136 default:
5137 vSetEventFlag(g_ncmd_evid, 1);
5138 return 0;
5139 }
5140 g_cdvdman_istruct.m_read_mode = *mode;
5141 g_cdvdman_istruct.m_read_callback = callback;
5142 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
5143 g_cdvdman_istruct.m_read_lsn = lsn;
5144 g_cdvdman_istruct.m_read_sectors = sectors;
5145 *(u32 *)ndata = lsn;
5146 *(u32 *)&ndata[4] = sectors;
5147 ndata[8] = mode->trycount;
5148 ndata[9] = cdvdman_speedctl(mode->spindlctrl, g_cdvdman_istruct.m_dvd_flag, lsn + sectors);
5149 g_cdvdman_istruct.m_read_buf = buffer;
5150 ndata[10] = mode->datapattern;
5151 dma3_param.m_dma3_maddress = buffer;
5152 VERBOSE_KPRINTF(1, "Read Command call\n");
5153 if ( cdvdman_send_ncmd(6, ndata, sizeof(ndata), 1, &dma3_param, 0) < 0 )
5154 {
5155 vSetEventFlag(g_ncmd_evid, 1);
5156 return 0;
5157 }
5158 vSetEventFlag(g_ncmd_evid, 1);
5159 return 1;
5160}
5161
5162static int read_cdvd_cb(cdvdman_internal_struct_t *common)
5163{
5164 int sblock;
5165 int i;
5166 u32 cdreadlsn;
5167 int syncdec_res_1;
5168 sceCdlLOCCD cdrloc;
5169
5170 sblock = 0;
5171 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
5172 {
5173 char syncdec_res_4;
5174 int errlsn;
5175
5176 syncdec_res_4 = 0;
5177 if ( common->m_read2_flag == 3 )
5178 {
5179 sblock = 0x924;
5180 cdrloc.minute = cdvdman_syncdec(
5181 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
5182 cdrloc.second = cdvdman_syncdec(
5183 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1]);
5184 cdrloc.sector = cdvdman_syncdec(
5185 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2]);
5186 cdreadlsn = sceCdPosToInt(&cdrloc);
5187 }
5188 else
5189 {
5190 sblock = 0x810;
5191 syncdec_res_1 = (u8)cdvdman_syncdec(
5192 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 3]);
5193 syncdec_res_1 +=
5194 (u8)cdvdman_syncdec(
5195 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2])
5196 << 8;
5197 syncdec_res_1 +=
5198 (u8)cdvdman_syncdec(
5199 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1])
5200 << 16;
5201 syncdec_res_4 = cdvdman_syncdec(
5202 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
5203 if ( !common->m_cdvdman_dma3sec && !common->m_interupt_read_state )
5204 {
5205 common->m_interupt_read_state = (syncdec_res_4 & 0xC) | (((syncdec_res_4 & 0xC) && i) ? 0x80 : 0);
5206 }
5207 cdreadlsn = (syncdec_res_1 - 0x30000) + (( common->m_opo_or_para && ((unsigned int)(common->m_cdvdman_lsn + common->m_cdvdman_csec + i) >= common->m_layer_1_lsn && common->m_opo_or_para == 1) ) ? common->m_layer_1_lsn : 0);
5208 }
5209 errlsn = common->m_cdvdman_lsn + common->m_cdvdman_csec + common->m_cdvdman_dma3sec + i;
5210 if ( cdreadlsn != (u32)errlsn )
5211 {
5212 VERBOSE_KPRINTF(
5213 1, "Read_IOP Sector_ID error lsn= %d readlsn= %d layer= %d\n", errlsn, cdreadlsn, (syncdec_res_4 & 1));
5214 break;
5215 }
5216 }
5217 if ( i == common->m_dma3_param.m_dma3_csectors )
5218 {
5219 unsigned int size;
5220
5221 size = 0;
5222 switch ( common->m_cdvdman_pattern )
5223 {
5224 case 0:
5225 size = 0x800;
5226 break;
5227 case 1:
5228 default:
5229 size = 0x918;
5230 break;
5231 case 2:
5232 optimized_memcpy(
5233 &((char *)(common->m_cdvdman_rbuffer))[0x924 * common->m_cdvdman_dma3sec],
5234 (const char *)g_cdvdman_ptoc,
5235 0x924 * i);
5236 break;
5237 }
5238 if ( size )
5239 {
5240 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
5241 {
5242 optimized_memcpy(
5243 &((char *)(common->m_cdvdman_rbuffer))[(common->m_cdvdman_dma3sec + i) * size],
5244 (const char *)&g_cdvdman_ptoc[12 + (i * sblock)],
5245 size);
5246 }
5247 }
5248 g_cdvdman_readptr = common->m_cdvdman_csec + common->m_cdvdman_dma3sec;
5249 }
5250 else
5251 {
5252 common->m_sync_error += 1;
5253 }
5254 return 1;
5255}
5256
5257static int cdvdman_read(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int decflag, int shift, int ef1, int ef2)
5258{
5259 int read_res;
5260 int state;
5261 int scres_unused;
5262 int dvd;
5263
5264 dvd = cdvdman_isdvd();
5265 if ( dvd )
5266 {
5267 if ( !DvdDual_infochk() )
5268 {
5269 if ( ef1 )
5270 {
5271 vSetEventFlag(ef1, ef2);
5272 }
5273 return 0;
5274 }
5275 lsn = sceCdLsnDualChg(lsn);
5276 }
5277 else if ( mode->datapattern == SCECdSecS2328 || (g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state) )
5278 {
5279 int read0_res;
5280
5281 if ( g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state && mode->spindlctrl == SCECdSpinNom )
5282 {
5283 mode->spindlctrl = SCECdSpinStm;
5284 }
5285 CpuSuspendIntr(&state);
5286 read0_res = sceCdRead0(lsn, sectors, buf, mode, 0, 0);
5287 if ( ef1 )
5288 {
5289 vSetEventFlag(ef1, ef2);
5290 }
5291 CpuResumeIntr(state);
5292 return read0_res;
5293 }
5294 CpuSuspendIntr(&state);
5295 if ( (sceCdDiskReady(8) & 0xC0) != 0x40 || g_cdvdman_istruct.m_read2_flag )
5296 {
5297 VERBOSE_KPRINTF(
5298 1,
5299 "sceCdRead: Double Booking error r2f= %d waf= %d\n",
5300 g_cdvdman_istruct.m_read2_flag,
5301 g_cdvdman_istruct.m_wait_flag);
5302 if ( ef1 )
5303 {
5304 vSetEventFlag(ef1, ef2);
5305 }
5306 CpuResumeIntr(state);
5307 return 0;
5308 }
5309 if ( decflag )
5310 {
5311 g_cdvdman_istruct.m_dec_shift = shift;
5312 g_cdvdman_istruct.m_dec_state = 1;
5313 }
5314 g_cdvdman_readbuf = buf;
5315 g_cdvdman_readptr = 0;
5316 g_cdvdman_istruct.m_cdvdman_lsn = lsn;
5317 g_cdvdman_istruct.m_cdvdman_csec = 0;
5318 g_cdvdman_istruct.m_cdvdman_nsec = sectors;
5319 g_cdvdman_istruct.m_cdvdman_rbuffer = (int)buf;
5320 g_cdvdman_istruct.m_cdvdman_pattern = dvd ? SCECdSecS2048 : mode->datapattern;
5321 g_cdvdman_istruct.m_cdvdman_cdrmode.trycount = mode->trycount;
5322 g_cdvdman_istruct.m_cdvdman_cdrmode.spindlctrl = mode->spindlctrl;
5323 g_cdvdman_istruct.m_cdvdman_cdrmode.datapattern = dvd ? SCECdSecS2048 : SCECdSecS2340;
5324 g_cdvdman_istruct.m_read2_flag = dvd ? 1 : 3;
5325 g_cdvdman_istruct.m_sync_error = 0;
5326 g_cdvdman_istruct.m_interupt_read_state = 0;
5327 g_cdvdman_istruct.m_cdvdman_rsec = (sectors >= 0x41) ? (((lsn & 0xF)) ? (0x10 - (lsn & 0xF)) : 0x40) : sectors;
5328 g_cdvdman_read_alarm_cb_timeout.hi = 0;
5329 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
5330 vSetAlarm(
5331 &g_cdvdman_read_alarm_cb_timeout,
5332 (unsigned int (*)(void *))read_timeout_alarm_cb,
5333 &g_cdvdman_read_alarm_cb_timeout);
5334 read_res = (dvd ? sceCdRV : sceCdRead0)(
5335 lsn,
5336 g_cdvdman_istruct.m_cdvdman_rsec,
5337 g_cdvdman_ptoc,
5338 dvd ? mode : &g_cdvdman_istruct.m_cdvdman_cdrmode,
5339 0x10,
5340 read_cdvd_cb);
5341 if ( !read_res )
5342 {
5343 g_cdvdman_istruct.m_last_error = SCECdErREADCFR;
5344 g_cdvdman_istruct.m_cdvdman_rsec = 0;
5345 g_cdvdman_istruct.m_read2_flag = 0;
5346 if ( g_cdvdman_istruct.m_dec_state )
5347 {
5348 g_cdvdman_istruct.m_dec_shift = 0;
5349 g_cdvdman_istruct.m_check_version = 0;
5350 g_cdvdman_istruct.m_dec_state = 0;
5351 sceCdDecSet(0, 0, 0);
5352 }
5353 vCancelAlarm((unsigned int (*)(void *))read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5354 }
5355 if ( ef1 )
5356 {
5357 vSetEventFlag(ef1, ef2);
5358 }
5359 CpuResumeIntr(state);
5360 return !!read_res;
5361}
5362
5363int sceCdRE(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
5364{
5365 return cdvdman_read(lsn, sectors, buf, mode, 0, 0, 0, 0);
5366}
5367
5368int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
5369{
5370 iop_event_info_t efinfo;
5371 int state;
5372
5373 // Unofficial: initialize to 0
5374 memset(&efinfo, 0, sizeof(efinfo));
5375 CpuSuspendIntr(&state);
5376 vReferEventFlagStatus(g_fio_fsv_evid, &efinfo);
5377 if ( !(efinfo.currBits & 1) )
5378 {
5379 CpuResumeIntr(state);
5380 return 0;
5381 }
5382 vClearEventFlag(g_fio_fsv_evid, ~1);
5383 CpuResumeIntr(state);
5384 return cdvdman_read(lbn, sectors, buffer, mode, 0, 0, g_fio_fsv_evid, 1);
5385}
5386
5387static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data)
5388{
5389 return decflag ? ((u8)(((u8)data << (shift % 8)) | ((u8)data >> (8 - shift % 8))) ^ (u8)decxor) : (u8)data;
5390}
5391
5392static void Read2intrCDVD(int read2_flag)
5393{
5394 iCancelAlarm((unsigned int (*)(void *))read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5395 if ( g_cdvdman_istruct.m_last_error || g_cdvdman_retries >= 5 )
5396 {
5397 if ( !g_cdvdman_istruct.m_last_error )
5398 {
5399 g_cdvdman_istruct.m_last_error = SCECdErREADCF;
5400 }
5401 g_cdvdman_istruct.m_read2_flag = 0;
5402 g_cdvdman_retries = 0;
5403 g_cdvdman_rtindex = 0;
5404 g_cdvdman_readptr = 0;
5405 if ( g_cdvdman_istruct.m_dec_state )
5406 {
5407 g_cdvdman_istruct.m_dec_shift = 0;
5408 g_cdvdman_istruct.m_check_version = 0;
5409 g_cdvdman_istruct.m_dec_state = 0;
5410 }
5411 g_cdvdman_istruct.m_interupt_read_state = 0;
5412 }
5413 else if ( !g_cdvdman_istruct.m_interupt_read_state || g_cdvdman_istruct.m_cdvdman_csec )
5414 {
5415 int scres_unused;
5416
5417 g_cdvdman_istruct.m_interupt_read_state = 0;
5418 if ( g_cdvdman_istruct.m_sync_error )
5419 {
5420 u32 lsn_tmp;
5421
5422 if ( !g_cdvdman_rtindex )
5423 {
5424 g_cdvdman_rtindex = 3;
5425 g_cdvdman_retries += 1;
5426 }
5427 g_cdvdman_istruct.m_sync_error = 0;
5428 lsn_tmp = g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec;
5429 if ( lsn_tmp >= 0x30 )
5430 {
5431 lsn_tmp -= 0x10 * (g_cdvdman_rtindex - 1);
5432 }
5433 else
5434 {
5435 lsn_tmp += 0x10 * (g_cdvdman_rtindex - 1);
5436 }
5437 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
5438 lsn_tmp,
5439 g_cdvdman_istruct.m_cdvdman_rsec,
5440 g_cdvdman_ptoc,
5441 &g_cdvdman_istruct.m_cdvdman_cdrmode,
5442 0x10,
5443 read_cdvd_cb) )
5444 {
5445 g_cdvdman_read_alarm_cb_timeout.hi = 0;
5446 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
5447 iSetAlarm(
5448 &g_cdvdman_read_alarm_cb_timeout,
5449 (unsigned int (*)(void *))read_timeout_alarm_cb,
5450 &g_cdvdman_read_alarm_cb_timeout);
5451 }
5452 else
5453 {
5454 VERBOSE_KPRINTF(1, "Retry Read Fatal Error\n");
5455 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
5456 g_cdvdman_istruct.m_read2_flag = 0;
5457 g_cdvdman_retries = 0;
5458 g_cdvdman_rtindex = 0;
5459 g_cdvdman_readptr = 0;
5460 if ( g_cdvdman_istruct.m_dec_state )
5461 {
5462 g_cdvdman_istruct.m_dec_shift = 0;
5463 g_cdvdman_istruct.m_check_version = 0;
5464 g_cdvdman_istruct.m_dec_state = 0;
5465 }
5466 }
5467 g_cdvdman_rtindex -= !!g_cdvdman_rtindex;
5468 }
5469 else
5470 {
5471 int cdsectorsz;
5472
5473 g_cdvdman_retries = 0;
5474 switch ( g_cdvdman_istruct.m_cdvdman_pattern )
5475 {
5476 case 0:
5477 cdsectorsz = 0x800;
5478 break;
5479 case 1:
5480 default:
5481 cdsectorsz = 0x918;
5482 break;
5483 case 2:
5484 cdsectorsz = 0x924;
5485 break;
5486 }
5487 g_cdvdman_istruct.m_cdvdman_rbuffer += cdsectorsz * g_cdvdman_istruct.m_cdvdman_rsec;
5488 g_cdvdman_istruct.m_cdvdman_csec += g_cdvdman_istruct.m_cdvdman_rsec;
5489 if ( (unsigned int)g_cdvdman_istruct.m_cdvdman_csec < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec )
5490 {
5491 g_cdvdman_istruct.m_cdvdman_rsec =
5492 ((unsigned int)(g_cdvdman_istruct.m_cdvdman_csec + 0x40) < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec) ?
5493 0x40 :
5494 (g_cdvdman_istruct.m_cdvdman_nsec - g_cdvdman_istruct.m_cdvdman_csec);
5495 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
5496 g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec,
5497 g_cdvdman_istruct.m_cdvdman_rsec,
5498 g_cdvdman_ptoc,
5499 &g_cdvdman_istruct.m_cdvdman_cdrmode,
5500 0x10,
5501 read_cdvd_cb) )
5502 {
5503 g_cdvdman_read_alarm_cb_timeout.hi = 0;
5504 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
5505 iSetAlarm(
5506 &g_cdvdman_read_alarm_cb_timeout,
5507 (unsigned int (*)(void *))read_timeout_alarm_cb,
5508 &g_cdvdman_read_alarm_cb_timeout);
5509 }
5510 else
5511 {
5512 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
5513 g_cdvdman_istruct.m_read2_flag = 0;
5514 g_cdvdman_readptr = 0;
5515 if ( g_cdvdman_istruct.m_dec_state )
5516 {
5517 g_cdvdman_istruct.m_dec_shift = 0;
5518 g_cdvdman_istruct.m_check_version = 0;
5519 g_cdvdman_istruct.m_dec_state = 0;
5520 }
5521 }
5522 }
5523 else
5524 {
5525 g_cdvdman_istruct.m_read2_flag = 0;
5526 g_cdvdman_readptr = 0;
5527 if ( g_cdvdman_istruct.m_dec_state )
5528 {
5529 g_cdvdman_istruct.m_dec_shift = 0;
5530 g_cdvdman_istruct.m_check_version = 0;
5531 g_cdvdman_istruct.m_dec_state = 0;
5532 }
5533 }
5534 }
5535 }
5536 else
5537 {
5538 g_cdvdman_istruct.m_last_error = ((g_cdvdman_istruct.m_interupt_read_state & 0x80)) ? SCECdErREADCF : SCECdErIPI;
5539 g_cdvdman_istruct.m_interupt_read_state = 0;
5540 VERBOSE_KPRINTF(1, "IPIerr emu Hit Dummy Err %02x\n", (u8)g_cdvdman_istruct.m_last_error);
5541 g_cdvdman_istruct.m_read2_flag = 0;
5542 g_cdvdman_retries = 0;
5543 g_cdvdman_rtindex = 0;
5544 g_cdvdman_readptr = 0;
5545 if ( g_cdvdman_istruct.m_dec_state )
5546 {
5547 g_cdvdman_istruct.m_dec_shift = 0;
5548 g_cdvdman_istruct.m_check_version = 0;
5549 g_cdvdman_istruct.m_dec_state = 0;
5550 }
5551 }
5552}
5553
5555{
5556 (void)tag;
5557 (void)mode;
5558
5559 return 0;
5560}
5561
5562static int cdvdman_readfull(u32 lsn, u32 sectors, void *buf, const sceCdRMode *mode, int flag)
5563{
5564 cdvdman_dma3_parameter_t dma3_param;
5565 char ndata[11];
5566
5567 VERBOSE_KPRINTF(1, "lsn:%d nsec:%d buf:% cmdmode:%d\n", lsn, sectors, buf, flag);
5568 g_cdvdman_readbuf = buf;
5569 dma3_param.m_dma3_csectors = 0;
5570 dma3_param.m_dma3_msectors = 0;
5571 dma3_param.m_dma3_callback = 0;
5572 dma3_param.m_dma3_blkcount = sectors;
5573 switch ( mode->datapattern )
5574 {
5575 case SCECdSecS2328:
5576 dma3_param.m_dma3_blkwords = 8;
5577 dma3_param.m_dma3_blkcount *= 74;
5578 dma3_param.m_cdvdreg_howto = 136;
5579 break;
5580 case SCECdSecS2340:
5581 dma3_param.m_dma3_blkwords = 12;
5582 dma3_param.m_dma3_blkcount *= 51;
5583 dma3_param.m_cdvdreg_howto = 140;
5584 break;
5585 case SCECdSecS2048:
5586 default:
5587 dma3_param.m_dma3_blkwords = 12;
5588 dma3_param.m_dma3_blkcount *= 49;
5589 dma3_param.m_cdvdreg_howto = 140;
5590 break;
5591 }
5592 // The following call to sceCdGetDiskType() was inlined
5593 switch ( sceCdGetDiskType() )
5594 {
5595 case SCECdPSCDDA:
5596 case SCECdPS2CDDA:
5597 case SCECdCDDA:
5598 break;
5599 default:
5600 return 0;
5601 }
5602 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
5603 {
5604 return 0;
5605 }
5606 *(u32 *)ndata = lsn;
5607 *(u32 *)&ndata[4] = sectors;
5608 ndata[8] = mode->trycount;
5609 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 0, lsn + sectors);
5610 dma3_param.m_dma3_maddress = buf;
5611 ndata[10] = mode->datapattern;
5612 return cdvdman_send_ncmd((!flag) ? 7 : 14, ndata, sizeof(ndata), (!flag) ? 2 : 12, &dma3_param, 1) >= 0;
5613}
5614
5615int sceCdReadCDDA(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
5616{
5617 return cdvdman_readfull(lbn, sectors, buffer, mode, 0);
5618}
5619
5620int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
5621{
5622 cdvdman_dma3_parameter_t dma3_param;
5623 char ndata[11];
5624 u32 efbits;
5625
5626 // The following call to sceCdGetDiskType was inlined
5627 if (
5628 sceCdGetDiskType() != SCECdPS2DVD || (g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF)
5629 || (PollEventFlag(g_ncmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND) )
5630 {
5631 return 0;
5632 }
5633 VERBOSE_KPRINTF(
5634 1, "RV read: sec %d num %d spin %d trycnt %d addr %08x\n", lsn, sectors, mode->spindlctrl, mode->trycount, buf);
5635 g_cdvdman_readbuf = buf;
5636 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
5637 g_cdvdman_istruct.m_read_mode = *mode;
5638 g_cdvdman_istruct.m_read_lsn = lsn;
5639 g_cdvdman_istruct.m_read_sectors = sectors;
5640 *(u32 *)ndata = lsn;
5641 *(u32 *)&ndata[4] = sectors;
5642 ndata[8] = mode->trycount;
5643 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 1, lsn + sectors);
5644 ndata[10] = 0;
5645 dma3_param.m_dma3_csectors = (arg5 && (sectors < (u32)arg5)) ? sectors : (u32)arg5;
5646 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
5647 dma3_param.m_cdvdreg_howto = 140;
5648 dma3_param.m_dma3_blkwords = 12;
5649 g_cdvdman_istruct.m_read_buf = buf;
5650 dma3_param.m_dma3_blkcount = (!arg5) ? sectors : 1;
5651 dma3_param.m_dma3_blkcount *= 43;
5652 dma3_param.m_dma3_msectors = sectors;
5653 dma3_param.m_dma3_callback = (int (*)(void))cb;
5654 g_cdvdman_istruct.m_read_callback = cb;
5655 dma3_param.m_dma3_maddress = buf;
5656 if ( cdvdman_send_ncmd(8, ndata, sizeof(ndata), 14, &dma3_param, 0) < 0 )
5657 {
5658 vSetEventFlag(g_ncmd_evid, 1);
5659 return 0;
5660 }
5661 vSetEventFlag(g_ncmd_evid, 1);
5662 return 1;
5663}
5664
5665int sceCdSeek(u32 lbn)
5666{
5667 u32 ndata;
5668
5669 ndata = lbn;
5670 if ( cdvdman_isdvd() )
5671 {
5672 if ( !DvdDual_infochk() )
5673 {
5674 return 0;
5675 }
5676 ndata = sceCdLsnDualChg(ndata);
5677 }
5678 return cdvdman_send_ncmd(5, &ndata, 4, 4, 0, 1) >= 0;
5679}
5680
5681int sceCdRI(u8 *buffer, u32 *result)
5682{
5683 int command;
5684 u8 rdata[9];
5685
5686 command = set_prev_command(18, 0, 0, (char *)rdata, sizeof(rdata), 1);
5687 *result = rdata[0];
5688 memcpy(buffer, &rdata[1], 8);
5689 return command;
5690}
5691
5692int sceCdRM(char *buffer, u32 *status)
5693{
5694 int command;
5695 int cmd_tmp2;
5696 u8 rdata[9];
5697 char wdata;
5698 u32 efbits;
5699
5700 *status = 0;
5701 if ( sceCdGetMVersion(rdata, status) != 1 || (unsigned int)(rdata[3] | (rdata[2] << 8) | (rdata[1] << 16)) < 0x10500 )
5702 {
5703 strcpy(buffer, "M_NAME_UNKNOWN");
5704 buffer[15] = 0;
5705 *status |= 0x40;
5706 return 1;
5707 }
5708 if ( PollEventFlag(g_scmd_evid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5709 {
5710 return 0;
5711 }
5712 DelayThread(2000);
5713 wdata = 0;
5714 command = set_prev_command(0x17, &wdata, sizeof(wdata), (char *)rdata, sizeof(rdata), 0);
5715 *status = rdata[0];
5716 memcpy(buffer, &rdata[1], 8);
5717 DelayThread(2000);
5718 wdata = 8;
5719 cmd_tmp2 = set_prev_command(0x17, &wdata, sizeof(wdata), (char *)rdata, sizeof(rdata), 0);
5720 *status |= rdata[0];
5721 memcpy(&buffer[8], &rdata[1], 8);
5722 vSetEventFlag(g_scmd_evid, 1);
5723 return command ? (!!cmd_tmp2) : 0;
5724}
5725
5726static int sceCdGetMVersion(u8 *buffer, u32 *status)
5727{
5728 int command;
5729 char rdata[4];
5730 char wdata[1];
5731
5732 wdata[0] = 0;
5733 command = set_prev_command(3, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
5734 *status = rdata[0] & 0x80;
5735 VERBOSE_KPRINTF(1, "MV 0x%02x,0x%02x,0x%02x,0x%02x\n", (u8)rdata[0], (u8)rdata[1], (u8)rdata[2], (u8)rdata[3]);
5736 rdata[0] &= ~0x80;
5737 memcpy(buffer, rdata, sizeof(rdata));
5738 return command;
5739}
5740
5741static int cdvdman_scmd_sender_03_48(u8 *buf, u32 *status)
5742{
5743 int retval;
5744 char rdata[2];
5745 char wdata[2];
5746
5747 if ( g_cdvdman_minver_50000 )
5748 {
5749 return 0;
5750 }
5751 wdata[0] = 48;
5752 wdata[1] = 2;
5753 retval = set_prev_command(3, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
5754 *status = (u8)rdata[0];
5755 *buf = rdata[1];
5756 return retval;
5757}
5758
5759int sceCdMmode(int media)
5760{
5761 g_cdvdman_mmode = media;
5762 return 1;
5763}
5764
5765int sceCdCancelPOffRdy(u32 *result)
5766{
5767 char wdata[8];
5768
5769 memset(wdata, 0, sizeof(wdata));
5770 *result = 0;
5771 return g_cdvdman_minver_20400 ? set_prev_command(27, wdata, 0, (char *)result, 1, 1) : 1;
5772}
5773
5774static unsigned int power_off_alarm_cb(cdvdman_internal_struct_t *s)
5775{
5776 s->m_power_flag = 0;
5777 return 0;
5778}
5779
5780int sceCdPowerOff(u32 *result)
5781{
5782 int command;
5783
5784 *result = 0;
5785 VERBOSE_KPRINTF(1, "sceCdPowerOff Call\n");
5786 if ( !g_cdvdman_minver_x_model_15 )
5787 {
5788 while ( (sceCdStatus() & SCECdStatShellOpen) )
5789 {
5790 u32 traychk;
5791
5792 sceCdTrayReq(SCECdTrayClose, &traychk);
5793 vDelayThread(250000);
5794 }
5795 }
5796 command = set_prev_command(0xF, 0, 0, (char *)result, 1, 1);
5797 if ( !command )
5798 {
5799 g_cdvdman_istruct.m_power_flag = 0;
5800 return 0;
5801 }
5802 KPRINTF("PowerOff Start...\n");
5803 g_cdvdman_istruct.m_power_flag = 1;
5804 g_cdvdman_power_off_timeout.hi = 0;
5805 g_cdvdman_power_off_timeout.lo = 0xAFC8000;
5806 vSetAlarm(&g_cdvdman_power_off_timeout, (unsigned int (*)(void *))power_off_alarm_cb, &g_cdvdman_istruct);
5807 return command;
5808}
5809
5810int sceCdCtrlADout(int mode, u32 *status)
5811{
5812 char wdata;
5813
5814 wdata = mode;
5815 *status = 0;
5816 DelayThread(2000);
5817 VERBOSE_KPRINTF(1, "Audio Digital Out: Set param %d\n", wdata);
5818 return set_prev_command(20, &wdata, sizeof(wdata), (char *)status, 1, 1);
5819}
5820
5822{
5823 int retval;
5824
5825 retval = set_prev_command(8, 0, 0, (char *)clock, 8, 1);
5826 clock->pad = 0;
5827 clock->month &= 0x7F;
5828 if ( retval && !clock->stat )
5829 {
5830 memcpy(&g_cdvdman_clock, clock, sizeof(g_cdvdman_clock));
5831 g_cdvdman_clk_flg = 1;
5832 }
5833 else if ( g_cdvdman_clk_flg )
5834 {
5835 memcpy(clock, &g_cdvdman_clock, sizeof(g_cdvdman_clock));
5836 }
5837 else
5838 {
5839 clock->month = 3;
5840 clock->day = 4;
5841 clock->hour = 5;
5842 clock->minute = 6;
5843 clock->year = 0;
5844 clock->second = 7;
5845 }
5846 return retval;
5847}
5848
5849int sceCdRC(sceCdCLOCK *clock)
5850{
5851 return set_prev_command(8, 0, 0, (char *)clock, 8, 1);
5852}
5853
5854int sceCdTrayReq(int param, u32 *traychk)
5855{
5856 char wdata;
5857 char rdata;
5858
5859 if ( param == SCECdTrayCheck )
5860 {
5861 *traychk = cdvdman_mediactl(1);
5862 VERBOSE_KPRINTF(1, "Tray Req test = %d\n", *traychk);
5863 return 1;
5864 }
5865 if ( g_cdvdman_minver_x_model_15 && param == SCECdTrayClose )
5866 {
5867 return 1;
5868 }
5869 wdata = param;
5870 g_cdvdman_iocache = 0;
5871 if ( set_prev_command(6, &wdata, sizeof(wdata), &rdata, sizeof(rdata), 1) && !rdata )
5872 {
5873 vDelayThread(11000);
5874 return 1;
5875 }
5876 return 0;
5877}
5878
5879static int cdvdman_scmd_sender_3B(int arg1)
5880{
5881 char wdata;
5882 char rdata;
5883
5884 if ( g_cdvdman_minver_x_model_15 && arg1 == 1 )
5885 {
5886 return 1;
5887 }
5888 wdata = arg1;
5889 g_cdvdman_iocache = 0;
5890 if ( set_prev_command(59, &wdata, sizeof(wdata), &rdata, sizeof(rdata), 1) && !rdata )
5891 {
5892 vDelayThread(11000);
5893 return 1;
5894 }
5895 return 0;
5896}
5897
5898#ifdef CDVD_VARIANT_DNAS
5899int sceCdReadDiskID(unsigned int *id)
5900{
5901 sceCdRMode rmode;
5902 char sectbuf[2048];
5903 u32 efbits;
5904 USE_DEV5_MMIO_HWPORT();
5905
5906 *((u8 *)id + 4) = 0;
5907 *((u8 *)id + 3) = 0;
5908 *((u8 *)id + 2) = 0;
5909 *((u8 *)id + 1) = 0;
5910 *(u8 *)id = 0;
5911 switch ( sceCdGetDiskType() )
5912 {
5913 case SCECdPS2CD:
5914 case SCECdPS2CDDA:
5915 case SCECdPS2DVD:
5916 break;
5917 default:
5918 return 0;
5919 }
5920 rmode.spindlctrl = 18;
5921 rmode.datapattern = SCECdSecS2048;
5922 rmode.trycount = 0;
5923 sceCdRead0(0x4B, 1, sectbuf, &rmode, 0, 0);
5924 sceCdSync(3);
5925 if ( !cdvdman_ncmd_sender_0C(0, 0, 0x4B) )
5926 {
5927 return 0;
5928 }
5929 sceCdSync(3);
5930 if ( g_cdvdman_istruct.m_last_error )
5931 {
5932 return 0;
5933 }
5934 WaitEventFlag(g_scmd_evid, 1, WEF_AND, &efbits);
5935 if ( !(dev5_mmio_hwport->m_dev5_reg_038 & 4) )
5936 {
5937 vSetEventFlag(g_scmd_evid, 1);
5938 return 0;
5939 }
5940 *(u8 *)id = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
5941 *((u8 *)id + 1) = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
5942 *((u8 *)id + 2) = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
5943 *((u8 *)id + 3) = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
5944 *((u8 *)id + 4) = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
5945 vSetEventFlag(g_scmd_evid, 1);
5946 return 1;
5947}
5948
5949int sceCdDoesUniqueKeyExist(u32 *status)
5950{
5951 int disktype_tmp;
5952 u8 dev5_reg_038;
5953 sceCdRMode rmode;
5954 char ndata[7];
5955 int state;
5956 u32 efbits;
5957 USE_DEV5_MMIO_HWPORT();
5958
5959 disktype_tmp = 0;
5960 if ( !g_cdvdman_istruct.m_cd_inited )
5961 {
5962 *status = SCECdErCUD;
5963 return 0;
5964 }
5965 *status = 0;
5966 switch ( sceCdGetDiskType() )
5967 {
5968 case SCECdPS2CD:
5969 case SCECdPS2CDDA:
5970 disktype_tmp = 1;
5971 break;
5972 case SCECdPS2DVD:
5973 break;
5974 default:
5975 *status = SCECdErCUD;
5976 return 0;
5977 }
5978 CpuSuspendIntr(&state);
5979 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
5980 {
5981 *status = SCECdErREADCF;
5982 CpuResumeIntr(state);
5983 return 0;
5984 }
5985 if ( (sceCdStatus() & SCECdStatSpin) )
5986 {
5987 CpuResumeIntr(state);
5988 }
5989 else
5990 {
5991 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5992 CpuResumeIntr(state);
5993 sceCdSync(3);
5994 }
5995 CpuSuspendIntr(&state);
5996 rmode.spindlctrl = 18;
5997 rmode.datapattern = SCECdSecS2048;
5998 rmode.trycount = 0;
5999 if ( disktype_tmp )
6000 {
6001 unsigned int i;
6002
6003 for ( i = 0; i < 20; i += 1 )
6004 {
6005 sceCdRead0(0x4B + (0x10 * i), 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
6006 CpuResumeIntr(state);
6007 sceCdSync(3);
6008 CpuSuspendIntr(&state);
6009 }
6010 CpuResumeIntr(state);
6011 }
6012 else
6013 {
6014 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
6015 CpuResumeIntr(state);
6016 sceCdSync(3);
6017 }
6018 WaitEventFlag(g_scmd_evid, 1, WEF_AND, &efbits);
6019 CpuSuspendIntr(&state);
6020 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
6021 {
6022 *status = SCECdErREADCF;
6023 CpuResumeIntr(state);
6024 vSetEventFlag(g_scmd_evid, 1);
6025 return 0;
6026 }
6027 strcpy(&ndata[3], "K");
6028 ndata[6] = 0;
6029 ndata[5] = 0;
6030 ndata[2] = 0;
6031 ndata[1] = 0;
6032 ndata[0] = 0;
6033 if ( cdvdman_send_ncmd(12, ndata, sizeof(ndata), 0, 0, 1) < 0 )
6034 {
6035 *status = SCECdErREADCF;
6036 CpuResumeIntr(state);
6037 vSetEventFlag(g_scmd_evid, 1);
6038 return 0;
6039 }
6040 CpuResumeIntr(state);
6041 sceCdSync(3);
6042 if ( g_cdvdman_istruct.m_last_error )
6043 {
6044 *status = (u8)g_cdvdman_istruct.m_last_error;
6045 vSetEventFlag(g_scmd_evid, 1);
6046 return 0;
6047 }
6048 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
6049 vSetEventFlag(g_scmd_evid, 1);
6050 return (dev5_reg_038 & 5) == 5;
6051}
6052
6053static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3)
6054{
6055 char ndata[7];
6056
6057 ndata[1] = !!arg2;
6058 ndata[0] = arg1;
6059 ndata[2] = !!(arg2 >> 8);
6060 *(u32 *)&ndata[3] = !arg1 ? arg3 : 0;
6061 return cdvdman_send_ncmd(12, ndata, sizeof(ndata), 0, 0, 1) >= 0;
6062}
6063#endif
6064
6065int sceCdDecSet(u8 enable_xor, u8 enable_shift, u8 shiftval)
6066{
6067#ifdef CDVD_VARIANT_DNAS
6068 USE_DEV5_MMIO_HWPORT();
6069
6070 g_cdvdman_cd36key = enable_shift | shiftval;
6071 dev5_mmio_hwport->m_dev5_reg_03A = (16 * (shiftval & 7)) | ((!!enable_xor) << 1) | (!!enable_shift);
6072#endif
6073 return 1;
6074}
static cdda_toc toc
Definition cdrom.c:52
int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
Definition cdvdman.c:5620
int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
Definition cdvdman.c:4380
int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
int sceCdSpinCtrlIOP(u32 speed)
Definition cdvdman.c:2031
int sceCdReadDiskID(unsigned int *id)
#define ENOENT
Definition errno.h:23
#define EINVAL
Definition errno.h:63
#define EMFILE
Definition errno.h:67
#define ENOMEM
Definition errno.h:43
#define EIO
Definition errno.h:29
#define EBUSY
Definition errno.h:51
#define ENODEV
Definition errno.h:57
#define ECOMM
Definition errno.h:155
#define EPERM
Definition errno.h:21
int CpuResumeIntr(int state)
Definition intrman.c:227
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
Definition intrman.c:125
int ReleaseIntrHandler(int irq)
Definition intrman.c:167
int QueryIntrContext(void)
int DisableIntr(int irq, int *res)
Definition intrman.c:395
int CpuSuspendIntr(int *state)
Definition intrman.c:205
int EnableIntr(int irq)
Definition intrman.c:346
void * privdata
Definition ioman.h:61
int unit
Definition ioman.h:57
int mode
Definition ioman.h:55
#define IOP_DT_FSEXT
Definition iomanX.h:66
#define FIO_S_IXGRP
Definition iox_stat.h:71
#define FIO_S_IROTH
Definition iox_stat.h:76
#define FIO_S_IXUSR
Definition iox_stat.h:62
#define FIO_S_IRGRP
Definition iox_stat.h:67
#define FIO_S_IXOTH
Definition iox_stat.h:80
#define FIO_S_IRUSR
Definition iox_stat.h:58
#define FIO_S_IFDIR
Definition iox_stat.h:45
#define FIO_S_IFREG
Definition iox_stat.h:43
int sceCdBreak(void)
Definition cdi.c:25
int sceCdReadModelID(unsigned int *id)
int sceCdStStop(void)
Definition cdi.c:214
int sceCdStSeekF(unsigned int lsn)
Definition cdvdman.c:2320
char name[16]
void * sceCdPOffCallback(void(*func)(void *), void *addr)
Definition cdvdman.c:3388
int sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition cdi.c:114
int sceCdGetError(void)
Definition cdi.c:40
@ STMNBLK
int sceCdCancelPOffRdy(u32 *result)
Definition cdvdman.c:5765
int sceCdPowerOff(u32 *result)
Definition cdvdman.c:5780
int sceCdDoesUniqueKeyExist(u32 *status)
int sceCdStPause(void)
Definition cdi.c:219
int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
Definition cdi.c:179
int sceCdGetToc(u8 *toc)
Definition cdi.c:57
int sceCdInit(int mode)
Definition cdi.c:64
sceCdCBFunc sceCdCallback(sceCdCBFunc function)
Definition cdi.c:16
int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
Definition cdvdman.c:3843
int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
Definition cdi.c:167
int sceCdStatus(void)
Definition cdi.c:152
int sceCdReadGUID(u64 *guid)
int sceCdDiskReady(int mode)
Definition cdi.c:30
int sceCdPause(void)
Definition cdi.c:93
int sceCdRM(char *buffer, u32 *status)
Definition cdvdman.c:5692
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition cdvdman.c:2168
int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
Definition cdvdman.c:2038
int sceCdReadClock(sceCdCLOCK *clock)
Definition cdvdman.c:5821
u32 sceCdGetReadPos(void)
Definition cdi.c:45
int sceCdGetDiskType(void)
Definition cdi.c:35
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
Definition cdvdman.c:2160
int sceCdMmode(int media)
Definition cdi.c:86
int sceCdSync(int mode)
Definition cdi.c:109
int sceCdStResume(void)
Definition cdi.c:224
int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
Definition cdvdman.c:4363
int sceCdSeek(u32 lbn)
Definition cdi.c:142
int sceCdSetTimeout(int param, int timeout)
Definition cdvdman.c:1914
int sceCdStStart(u32 lbn, sceCdRMode *mode)
Definition cdi.c:202
@ SCECdSpinX1
@ SCECdSpinX2
@ SCECdSpinNm2
@ SCECdSpinStm
@ SCECdSpinNom
@ SCECdSpinMx
@ SCECdSpinX12
@ SCECdSpinX4
@ SCECdTrayCheck
@ SCECdTrayOpen
@ SCECdTrayClose
int sceCdStStat(void)
Definition cdi.c:209
void(* sceCdCBFunc)(int reason)
int sceCdDecSet(unsigned char enable_xor, unsigned char enable_shift, unsigned char shiftval)
Definition cdvdman.c:6065
int sceCdRI(u8 *buffer, u32 *result)
Definition cdvdman.c:5681
@ SCECdNODISC
@ SCECdIllegalMedia
@ SCECdPSCDDA
@ SCECdPSCD
@ SCECdDETCT
@ SCECdDVDV
@ SCECdDVDVR
@ SCECdPS2DVD
@ SCECdCDDA
@ SCECdPS2CDDA
@ SCECdPS2CD
@ SCECdErEOM
@ SCECdErIPI
@ SCECdErREAD
@ SCECdErABRT
@ SCECdErREADCF
@ SCECdErREADCFR
@ SCECdErNORDY
@ SCECdErTRMOPN
@ SCECdErCUD
int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
Definition cdi.c:98
int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
Definition cdvdman.c:4645
int sceCdStandby(void)
Definition cdi.c:147
int sceCdStSeek(u32 lbn)
Definition cdi.c:197
int sceCdRE(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
Definition cdvdman.c:5363
int sceCdStop(void)
Definition cdi.c:157
int sceCdReadChain(sceCdRChain *tag, sceCdRMode *mode)
Definition cdvdman.c:5554
int sceCdTrayReq(int param, u32 *traychk)
Definition cdi.c:162
int sceCdCtrlADout(int mode, u32 *status)
Definition cdvdman.c:5810
@ SCECdStatSpin
@ SCECdStatShellOpen
@ SCECdStatStop
@ SCECdEXIT
@ SCECdINIT
Definition cdvdman.c:27
Definition cdvdman.c:60
#define EA_MULTI
Definition thevent.h:35