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