PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
cdvdman.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12
13#include "iomanX.h"
14
15#include <cdvdman.h>
16
17#include <cdvd-ioctl.h>
18#include <dev5_mmio_hwport.h>
19#include <errno.h>
20#include <hdd-ioctl.h>
21#include <iop_mmio_hwport.h>
22#include <kerr.h>
23
24IRX_ID("cdvd_driver", 2, 38);
25// Based on the module from SCE SDK 3.1.0.
26
27extern struct irx_export_table _exp_cdvdman;
28
29#ifdef CDVD_VARIANT_OSD
30#define PRID $15
31
32#define _mfc0(reg) \
33 ({ \
34 u32 val; \
35 __asm__ volatile("mfc0 %0, " #reg : "=r"(val)); \
36 val; \
37 })
38
39#define mfc0(reg) _mfc0(reg)
40#endif
41
43{
44 int m_number;
45 int m_parent;
46 int m_extent;
47 char m_name[32];
49
50typedef struct cdvdman_fhinfo_
51{
52 u32 m_file_lsn;
53 u32 m_read_pos;
54 u32 m_file_size;
55 u32 m_filemode;
56 int m_fd_flags;
57 int m_fd_layer;
58 int m_cache_file_fd;
59 u8 *m_fd_rcvbuf;
60 u32 m_fd_rbsize;
61 void *m_max_cluster;
62 int m_sector_count_total;
63 int m_cluster_cur;
65
66typedef struct cdvdman_pathtbl_
67{
68 int m_cache_path_sz;
69 int m_lsn;
70 unsigned int m_nsec;
71 int m_layer;
72 unsigned int m_cache_hit_count;
74
76{
77 sceCdlFILE m_file_struct;
78 int m_flags;
80
81typedef struct iso9660_desc_
82{
83 // cppcheck-suppress unusedStructMember
84 unsigned char m_type[1];
85 unsigned char m_id[5];
86 // cppcheck-suppress unusedStructMember
87 unsigned char m_version[1];
88 // cppcheck-suppress unusedStructMember
89 unsigned char m_unused1[1];
90 // cppcheck-suppress unusedStructMember
91 unsigned char m_system_id[32];
92 // cppcheck-suppress unusedStructMember
93 unsigned char m_volume_id[32];
94 // cppcheck-suppress unusedStructMember
95 unsigned char m_unused2[8];
96 // cppcheck-suppress unusedStructMember
97 unsigned char m_volume_space_size[8];
98 // cppcheck-suppress unusedStructMember
99 unsigned char m_unused3[32];
100 // cppcheck-suppress unusedStructMember
101 unsigned char m_volume_set_size[4];
102 // cppcheck-suppress unusedStructMember
103 unsigned char m_volume_sequence_number[4];
104 // cppcheck-suppress unusedStructMember
105 unsigned char m_logical_block_size[4];
106 // cppcheck-suppress unusedStructMember
107 unsigned char m_path_table_size[8];
108 unsigned char m_type_l_path_table[4];
109 // cppcheck-suppress unusedStructMember
110 unsigned char m_opt_type_l_path_table[4];
111 // cppcheck-suppress unusedStructMember
112 unsigned char m_type_m_path_table[4];
113 // cppcheck-suppress unusedStructMember
114 unsigned char m_opt_type_m_path_table[4];
115 // cppcheck-suppress unusedStructMember
116 unsigned char m_root_directory_record[34];
117 // cppcheck-suppress unusedStructMember
118 unsigned char m_volume_set_id[128];
119 // cppcheck-suppress unusedStructMember
120 unsigned char m_publisher_id[128];
121 // cppcheck-suppress unusedStructMember
122 unsigned char m_preparer_id[128];
123 // cppcheck-suppress unusedStructMember
124 unsigned char m_application_id[128];
125 // cppcheck-suppress unusedStructMember
126 unsigned char m_copyright_file_id[37];
127 // cppcheck-suppress unusedStructMember
128 unsigned char m_abstract_file_id[37];
129 // cppcheck-suppress unusedStructMember
130 unsigned char m_bibliographic_file_id[37];
131 // cppcheck-suppress unusedStructMember
132 unsigned char m_creation_date[17];
133 // cppcheck-suppress unusedStructMember
134 unsigned char m_modification_date[17];
135 // cppcheck-suppress unusedStructMember
136 unsigned char m_expiration_date[17];
137 // cppcheck-suppress unusedStructMember
138 unsigned char m_effective_date[17];
139 // cppcheck-suppress unusedStructMember
140 unsigned char m_file_structure_version[1];
141 // cppcheck-suppress unusedStructMember
142 unsigned char m_unused4[1];
143 // cppcheck-suppress unusedStructMember
144 unsigned char m_application_data[512];
145 // cppcheck-suppress unusedStructMember
146 unsigned char m_unused5[653];
148
149typedef struct iso9660_path_
150{
151 unsigned char m_name_len[2];
152 unsigned char m_extent[4];
153 unsigned char m_parent[2];
154 unsigned char m_name[];
156
157typedef struct iso9660_dirent_
158{
159 unsigned char m_length[1];
160 unsigned char m_ext_attr_length[1];
161 unsigned char m_extent[8];
162 unsigned char m_size[8];
163 unsigned char m_date[7];
164 unsigned char m_flags[1];
165 unsigned char m_file_unit_size[1];
166 unsigned char m_interleave[1];
167 unsigned char m_volume_sequence_number[4];
168 unsigned char m_name_len[1];
169 unsigned char m_name[];
171
172static int cdrom_init(iop_device_t *dev);
173extern void cdvdman_termcall(int with_stop);
174static int cdrom_deinit(iop_device_t *dev);
175static int cdrom_dopen(iop_file_t *f, const char *dirname);
176static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf);
177static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf);
178static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4);
179static int cdrom_close(iop_file_t *f);
180static int cdrom_read(iop_file_t *f, void *buf, int nbytes);
181static int cdrom_ioctl(iop_file_t *f, int arg, void *param);
182static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen);
183static int
184cdrom_devctl(iop_file_t *f, const char *, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen);
185static int cdrom_lseek(iop_file_t *f, int offset, int pos);
186static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer);
187static int sceCdSearchDir(char *dirname, int layer);
188static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer);
189static int cdvdman_cmpname(const char *p, const char *q);
190static int CD_newmedia(int arg);
191static int cdvdman_finddir(int target_parent, const char *target_name);
192static int CD_cachefile(int dsec, int layer);
193static int disc_read(int size, int loc, void *buffer, int layer);
194static int path_tbl_init(u32 blocks, char *fname, int action);
195extern unsigned int optimized_memcpy(char *dst, const char *src, unsigned int n);
196static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *), void *arg);
197static int vCancelAlarm(unsigned int (*alarm_cb)(void *), void *arg);
198static int vSetEventFlag(int ef, u32 bits);
199static int vDelayThread(int usec);
200static int DvdDual_infochk();
201static void cdvdman_init();
202static void cdvdman_write_scmd(cdvdman_internal_struct_t *s);
203static int intrh_dma_3(void *userdata);
204static int cdvdman_mediactl(int code);
205#ifndef CDVD_VARIANT_XOSD
206static int cdvdman_ncmd_sender_06();
207#endif
208static int cdvdman_gettoc(u8 *toc);
209static int cdvdman_isdvd();
210static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func);
211static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data);
212static void Read2intrCDVD(int read2_flag);
213#ifndef CDVD_VARIANT_XOSD
214static int cdvdman_scmd_sender_03_30(u8 *buf, u32 *status);
215#endif
216static int cdvdman_scmd_sender_3B(int arg1);
217#ifdef CDVD_VARIANT_DNAS
218static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3);
219#endif
220#ifdef CDVD_VARIANT_XOSD
221static unsigned int sceCdChgSpdlCtrl(int mode);
222#endif
223#ifdef CDVD_VARIANT_XOSD
224static int cdvdman_change_drive(int mode);
225static int cdvdman_get_renewal_date(u8 *buffer, u32 *status);
226static int get_cdvd_register(int regnr);
227static int get_disk_type_ex();
228static int sc_ffffffd8(u32 *status);
229static int set_cdvd_dev5_base_addr_atapi(int mode);
230static int update_cd_mode_ps2_atapi(void);
231#endif
232
233static char g_cdvdman_cache_name[256] = "host0:";
234static int g_cdvdman_cache_sector_size_count = 1;
235static int g_cdvdman_srchspd = 0;
236static int g_cdvdman_spinctl = -1;
237static int g_cdvdman_spinnom = -1;
238static int g_cdvdman_trycnt = -1;
239static int g_cdvdman_iocache = 0;
240static unsigned int g_cdvdman_lcn_offset = 0;
241static unsigned int g_cdvdman_numbytes_offset = 0;
242static int g_cdvdman_strmerr = 0;
243
244IOMANX_RETURN_VALUE_IMPL(EIO);
245
246static iop_device_ops_t g_cdvdman_cddev_ops = {
247 &cdrom_init, // init,
248 &cdrom_deinit, // deinit,
249 IOMANX_RETURN_VALUE(EIO), // format,
250 &cdrom_open, // open,
251 &cdrom_close, // close,
252 &cdrom_read, // read,
253 IOMANX_RETURN_VALUE(EIO), // write,
254 &cdrom_lseek, // lseek,
255 &cdrom_ioctl, // ioctl,
256 IOMANX_RETURN_VALUE(EIO), // remove,
257 IOMANX_RETURN_VALUE(EIO), // mkdir,
258 IOMANX_RETURN_VALUE(EIO), // rmdir,
259 &cdrom_dopen, // dopen,
260 &cdrom_close, // close,
261 &cdrom_dread, // dread
262 &cdrom_getstat, // getstat
263 IOMANX_RETURN_VALUE(EIO), // chstat,
264 IOMANX_RETURN_VALUE(EIO), // rename,
265 IOMANX_RETURN_VALUE(EIO), // chdir
266 IOMANX_RETURN_VALUE(EIO), // sync
267 IOMANX_RETURN_VALUE(EIO), // mount,
268 IOMANX_RETURN_VALUE(EIO), // umount,
269 IOMANX_RETURN_VALUE_S64(EIO), // lseek64,
270 &cdrom_devctl, // devctl,
271 IOMANX_RETURN_VALUE(EIO), // readdir,
272 IOMANX_RETURN_VALUE(EIO), // readlink,
273 &cdrom_ioctl2, // ioctl2,
274};
275static iop_device_t g_cdvdman_cddev = {"cdrom", IOP_DT_FSEXT | IOP_DT_FS, 1, "CD-ROM ", &g_cdvdman_cddev_ops};
276static int g_cdvdman_sync_timeout = 15000;
277static int g_cdvdman_stream_timeout = 5000;
278#ifdef CDVD_VARIANT_DNAS
279static iop_sys_clock_t g_readid_systemtime = {0, 0};
280#endif
281static int g_verbose_level = 0;
282static cdvdman_pathtbl_t *g_cdvdman_pathtbl = NULL;
283static unsigned int g_cache_count = 0;
284static unsigned int g_cache_table = 0;
285static unsigned int g_cdvdman_pathtblsize = 0;
286static int g_cache_path_size = 0;
287static int g_cache_path_fd = -1;
288static int g_cdvdman_fs_cdsec = 0;
289static int g_cdvdman_fs_layer = -1;
290static int g_cdvdman_fs_cache = 0;
291static int g_cdvdman_fs_base2 = 0;
292#ifdef CDVD_VARIANT_XOSD
293static vu8 *g_cdvdreg_bf801460 = (vu8 *)0xBF801460; // &iop_mmio_hwport->dev9c[0]
294// static u8 *cdvdreg_bf801462 = 0xBF801462;
295static vu8 *g_cdvdreg_bf801464 = (vu8 *)0xBF801464; // &iop_mmio_hwport->dev9c[4]
296static vu8 *g_cdvdreg_bf80146c = (vu8 *)0xBF80146C; // &iop_mmio_hwport->dev9c[0xC]
297// static u8 *cdvdreg_bf80146e = 0xBF80146E;
298static int g_cd_atapi_evfid = 0xFFFFFFFF;
299static int g_acmd_evfid = 0xFFFFFFFF;
300static int g_adma_evfid = 0xFFFFFFFF;
301#endif
302static int g_cdvdman_clk_flg = 0;
303static int g_cdvdman_cd36key = 0;
304static int g_cdvdman_ee_rpc_fno = 0;
305static int g_cdvdman_mmode = 0;
306static int g_cdvdman_last_cmdfunc = 0;
307static int g_cdvdman_minver_10700 = 0;
308static int g_cdvdman_minver_20200 = 0;
309static int g_cdvdman_minver_20400 = 0;
310static int g_cdvdman_minver_20800 = 0;
311static int g_cdvdman_emudvd9 = 0;
312static int g_cdvdman_minver_50000 = 0;
313static int g_cdvdman_minver_50200 = 0;
314static int g_cdvdman_minver_50400 = 0;
315static int g_cdvdman_minver_50600 = 0;
316static int g_cdvdman_minver_60000 = 0;
317static int g_cdvdman_minver_60200 = 0;
318#ifdef CDVD_VARIANT_OSD
319static int g_cdvdman_minver_60600 = 0;
320#endif
321#ifdef CDVD_VARIANT_XOSD
322static int g_cdvdman_vernotxxx1x = 0;
323#endif
324static int g_cdvdman_minver_x_model_15 = 0;
325#ifdef CDVD_VARIANT_XOSD
326static int g_cdvdman_debug_atapi_intr = 0;
327#endif
328static const char *g_masterdisc_header = "PlayStation Master Disc";
329static char g_cdvdman_ncmd = 0x06;
330static int g_cdvdman_chmedia = 0;
331static int g_cdvdman_chflags[4] = {1, 1, 1, 1};
332static int g_cdvdman_rtindex = 0;
333static int g_cdvdman_retries = 0;
334static u8 *g_cdvdman_ptoc;
335#ifdef CDVD_VARIANT_XOSD
336static int g_cdvdman_csys_evfid;
337#endif
338static int g_scmd_evfid;
339static void *g_cdvdman_temp_buffer_ptr;
340static int g_sfile_evfid;
341static int g_ncmd_evfid;
342#ifdef CDVD_VARIANT_OSD
343static s32 g_cdvdman_apply_scmd_sema;
344#endif
345static int g_fio_fsv_evfid;
346static int g_cdvdman_intr_evfid;
347#ifdef CDVD_VARIANT_XOSD
348static int (*g_cdvdman_atapi_eject_bs_power_callback)(int interrupt_nr, void *userdata);
349#endif
350static sceCdCBFunc g_cdvdman_user_cb;
351static void *g_cdvdman_power_off_callback_userdata;
352static void (*g_cdvdman_cdstm0cb)(int);
353static sceCdCLOCK g_cdvdman_clock;
354static void (*g_cdvdman_power_off_callback)(void *userdata);
355#ifdef CDVD_VARIANT_XOSD
356static void *g_cdvdman_atapi_eject_bs_power_callback_userdata;
357#endif
358static void (*g_cdvdman_cdstm1cb)(int);
359static int g_cdvdman_cmdfunc;
360static cdvdman_fhinfo_t g_cdvdman_fhinfo[16];
361static char g_cdvdman_sfname[1024];
362static cdvdman_filetbl_entry_t g_cdvdman_filetbl[64];
363static cdvdman_dirtbl_entry_t g_cdvdman_dirtbl[128];
364static int g_cdvdman_pathtblflag;
365static char g_cdvdman_fs_rbuf[0x800];
366static int g_cdvdman_readptr;
367static iop_sys_clock_t g_cdvdman_read_alarm_cb_timeout;
368static iop_sys_clock_t g_cdvdman_ncmd_timeout;
369static void *g_cdvdman_readbuf;
370static iop_sys_clock_t g_cdvdman_power_off_timeout;
371#ifdef CDVD_VARIANT_OSD
372static int g_cdvdman_config_numblocks;
373#endif
374static char g_cdvdman_fsvrbuf[42128];
375static cdvdman_internal_struct_t g_cdvdman_istruct;
376static const int g_cdvdman_cache_sector_count = 16;
377
378int _start(int ac, char **av)
379{
380 (void)ac;
381 (void)av;
382
383 if ( RegisterLibraryEntries(&_exp_cdvdman) )
384 {
385 return MODULE_NO_RESIDENT_END;
386 }
387 DelDrv(g_cdvdman_cddev.name);
388 if ( AddDrv(&g_cdvdman_cddev) )
389 {
390 cdrom_deinit(&g_cdvdman_cddev);
391 return MODULE_NO_RESIDENT_END;
392 }
393 g_cdvdman_ptoc = (u8 *)&g_cdvdman_fsvrbuf[0x924];
394 g_cdvdman_temp_buffer_ptr = g_cdvdman_fsvrbuf;
395 cdvdman_init();
396#if 0
397 SetRebootTimeLibraryHandlingMode(&_exp_cdvdman, 2);
398#else
399 // Call termination before disabling interrupts
400 _exp_cdvdman.mode &= ~6;
401 _exp_cdvdman.mode |= 2;
402#endif
403 return MODULE_RESIDENT_END;
404}
405
406void *sceGetFsvRbuf(void)
407{
408 return g_cdvdman_fsvrbuf;
409}
410
411static int cdrom_init(iop_device_t *dev)
412{
413 unsigned int i;
415#ifdef CDVD_VARIANT_OSD
416 iop_sema_t sema;
417#endif
418#ifdef CDVD_VARIANT_XOSD
419 USE_DEV5_MMIO_HWPORT();
420#endif
421 int scres_unused;
422
423 (void)dev;
424
425 PRINTF("cdvdman Init\n");
426 g_cdvdman_istruct.m_wait_flag = 1;
427 g_cdvdman_istruct.m_scmd_flag = 1;
428 g_cdvdman_istruct.m_read2_flag = 0;
429 g_cdvdman_istruct.m_stream_flag = 0;
430 g_cdvdman_istruct.m_last_error = SCECdErNO;
431 g_cdvdman_istruct.m_layer_1_lsn = 0;
432 g_cdvdman_istruct.m_use_toc = 0;
433 g_cdvdman_istruct.m_last_read_timeout = 0;
434 g_cdvdman_istruct.m_power_flag = 0;
435 g_cdvdman_istruct.m_current_dvd = 0;
436 g_cdvdman_istruct.m_dual_layer_emulation = 0;
437 g_cdvdman_istruct.m_dec_state = 0;
438 g_cdvdman_istruct.m_check_version = 0;
439 g_cdvdman_istruct.m_dec_shift = 0;
440 g_cdvdman_istruct.m_opo_or_para = -1;
441 g_cdvdman_istruct.m_no_dec_flag = 0;
442#ifdef CDVD_VARIANT_XOSD
443 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
444#endif
445 g_cdvdman_istruct.m_cd_inited = 0;
446#ifdef CDVD_VARIANT_XOSD
447 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = 0;
448 g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open = 1;
449#endif
450 g_cdvdman_istruct.m_tray_is_open = 0;
451 g_cdvdman_ee_rpc_fno = 0;
452 g_cdvdman_spinctl = -1;
453 event.attr = EA_MULTI;
454 event.bits = 0;
455 event.option = 0;
456 g_cdvdman_intr_evfid = CreateEventFlag(&event);
457 g_scmd_evfid = CreateEventFlag(&event);
458 g_ncmd_evfid = CreateEventFlag(&event);
459 g_sfile_evfid = CreateEventFlag(&event);
460 g_fio_fsv_evfid = CreateEventFlag(&event);
461#ifdef CDVD_VARIANT_XOSD
462 g_cdvdman_csys_evfid = CreateEventFlag(&event);
463#endif
464 ClearEventFlag(g_cdvdman_intr_evfid, ~0x4);
465 ClearEventFlag(g_cdvdman_intr_evfid, ~0x10);
466 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
467 SetEventFlag(g_ncmd_evfid, 1);
468 SetEventFlag(g_scmd_evfid, 1);
469 SetEventFlag(g_sfile_evfid, 1);
470 SetEventFlag(g_fio_fsv_evfid, 1);
471#ifdef CDVD_VARIANT_XOSD
472 SetEventFlag(g_cdvdman_csys_evfid, 1);
473#endif
474#ifdef CDVD_VARIANT_OSD
475 sema.attr = 1;
476 sema.initial = 1;
477 sema.max = 1;
478 sema.option = 0;
479 g_cdvdman_apply_scmd_sema = CreateSema(&sema);
480#endif
481 g_cdvdman_spinnom = -1;
482 g_cdvdman_trycnt = -1;
483 sceCdSC(0xFFFFFFF3, &scres_unused);
484 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
485 {
486 g_cdvdman_fhinfo[i].m_fd_flags = 0;
487 }
488#ifdef CDVD_VARIANT_XOSD
489 set_cdvd_dev5_base_addr_atapi(2);
490
491 for ( i = 0; i < 600 && !dev5_mmio_hwport->m_dev5_reg_015; i += 1 )
492 {
493 DelayThread(16000);
494 }
495 g_cdvdman_istruct.m_cd_mode_ps2_atapi =
496 (!(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) && !(dev5_mmio_hwport->m_dev5_reg_015 & 0x80)
497 && dev5_mmio_hwport->m_dev5_reg_00F != 6) ?
498 2 :
499 1;
500 KPRINTF("Mode %s Drive\n", g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1 ? "Atapi" : "PS2");
501 set_cdvd_dev5_base_addr_atapi(g_cdvdman_istruct.m_cd_mode_ps2_atapi);
502#endif
503 return 0;
504}
505
506void cdvdman_termcall(int with_stop)
507{
508 int i;
509 int oldstate;
510 USE_DEV5_MMIO_HWPORT();
511
512 VERBOSE_KPRINTF(1, "CDVD:library Terminate Call %d\n", with_stop);
513#ifdef CDVD_VARIANT_XOSD
514 if ( update_cd_mode_ps2_atapi() == 1 )
515 {
516 set_cdvd_dev5_base_addr_atapi(2);
517 }
518#endif
519 if ( with_stop )
520 {
521 return;
522 }
523 sceCdBreak();
524 sceCdSync(0);
525#ifndef CDVD_VARIANT_XOSD
526 if ( g_cdvdman_istruct.m_cd_inited )
527 {
528 cdvdman_ncmd_sender_06();
529 }
530#endif
531 for ( i = 0; i < 50000 && (dev5_mmio_hwport->m_dev5_reg_017 & 0x80); i += 1 )
532 {
533 DelayThread(100);
534 }
535 sceCdDecSet(0, 0, 0);
536 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
537 {
538 dev5_mmio_hwport->m_dev5_reg_007 = 1;
539 }
540 dmac_ch_set_chcr(3, 0);
541 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
542 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
543 DisableIntr(IOP_IRQ_CDVD, &oldstate);
544 ReleaseIntrHandler(IOP_IRQ_CDVD);
545}
546
547static int cdrom_deinit(iop_device_t *dev)
548{
549 unsigned int i;
550
551 (void)dev;
552
553 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
554 {
555 g_cdvdman_fhinfo[i].m_fd_flags = 0;
556 }
557 DeleteEventFlag(g_fio_fsv_evfid);
558 DeleteEventFlag(g_cdvdman_intr_evfid);
559 DeleteEventFlag(g_ncmd_evfid);
560 DeleteEventFlag(g_scmd_evfid);
561 DeleteEventFlag(g_sfile_evfid);
562#ifdef CDVD_VARIANT_XOSD
563 DeleteEventFlag(g_cdvdman_csys_evfid);
564#endif
565 return 0;
566}
567
568static int cdvdman_devready(void)
569{
570 int i;
571
572 for ( i = 0; i < 100; i += 1 )
573 {
574 // The following direct register access was replaced with call for ioprp300x
576 {
577 g_cdvdman_iocache = 0;
578 return -EIO;
579 }
580 // The following direct register access was replaced with call for ioprp300x
581 if ( (sceCdDiskReady(8) & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag && !g_cdvdman_ee_rpc_fno )
582 {
583 return 1;
584 }
585 DelayThread(10000);
586 }
587 return -EBUSY;
588}
589
590static int cdvdman_l0check(int layer)
591{
592 return !layer
593 && (g_cdvdman_istruct.m_dual_layer_emulation || g_cdvdman_istruct.m_opo_or_para == 1 || g_cdvdman_istruct.m_opo_or_para == 2);
594}
595
596static void cdvdman_iormode(sceCdRMode *rmode, int fmode, int layer)
597{
598 rmode->datapattern = SCECdSecS2048;
599 rmode->trycount = (g_cdvdman_trycnt == -1) ? 16 : g_cdvdman_trycnt;
600 if ( cdvdman_l0check(layer) )
601 {
602 if ( g_cdvdman_spinnom == -1 )
603 {
604 rmode->spindlctrl = (fmode == SCECdSpinX1 || fmode == SCECdSpinMx) ? fmode : SCECdSpinStm;
605 return;
606 }
607 if ( fmode != SCECdSpinX1 && fmode != SCECdSpinMx )
608 {
609 rmode->spindlctrl = SCECdSpinStm;
610 return;
611 }
612 rmode->spindlctrl = (u8)g_cdvdman_spinnom;
613 }
614 else if ( g_cdvdman_spinnom == -1 )
615 {
616 switch ( fmode )
617 {
618 case SCECdSpinStm:
619 rmode->spindlctrl = SCECdSpinStm;
620 break;
621 case SCECdSpinNom:
622 rmode->spindlctrl = SCECdSpinNom;
623 break;
624 case SCECdSpinX1:
625 rmode->spindlctrl = SCECdSpinX1;
626 break;
627 case SCECdSpinX2:
628 rmode->spindlctrl = SCECdSpinX2;
629 break;
630 case SCECdSpinX4:
631 rmode->spindlctrl = SCECdSpinX4;
632 break;
633 case SCECdSpinX12:
634 rmode->spindlctrl = SCECdSpinX12;
635 break;
636 case SCECdSpinMx:
637 rmode->spindlctrl = SCECdSpinMx;
638 break;
639 default:
640 rmode->spindlctrl = SCECdSpinNom;
641 break;
642 }
643 }
644}
645
646static int cdrom_dopen(iop_file_t *f, const char *dirname)
647{
648 unsigned int i;
649 int is_devready;
650 size_t path_name_ind;
651 int file_lsn_tmp;
652 char path_name[128];
653 u32 efbits;
654
655 VERBOSE_PRINTF(1, "fileIO DOPEN name= %s layer %d\n", dirname, f->unit);
656 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
657 for ( i = 0; (i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0]))) && g_cdvdman_fhinfo[i].m_fd_flags;
658 i += 1 )
659 {
660 }
661 if ( i == (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])) )
662 {
663 SetEventFlag(g_fio_fsv_evfid, 1);
664 return -EMFILE;
665 }
666 f->privdata = (void *)i;
667 is_devready = cdvdman_devready();
668 if ( is_devready < 0 )
669 {
670 SetEventFlag(g_fio_fsv_evfid, 1);
671 return is_devready;
672 }
673 strncpy(path_name, dirname, sizeof(path_name));
674 if ( !strcmp(path_name, ".") )
675 {
676 strcpy(path_name, "\\.");
677 }
678 path_name_ind = strlen(path_name);
679 path_name_ind -= (path_name_ind >= 2) ? 2 : 0;
680 if ( strcmp(&path_name[path_name_ind], "\\.") )
681 {
682 strcat(path_name, "\\.");
683 }
684 if ( (unsigned int)(f->unit) >= 2 )
685 {
686 PRINTF("open fail name %s\n", path_name);
687 SetEventFlag(g_fio_fsv_evfid, 1);
688 return -ENOENT;
689 }
690 g_cdvdman_fhinfo[i].m_file_lsn = 0;
691 g_cdvdman_srchspd = 0;
692 file_lsn_tmp = sceCdSearchDir(path_name, f->unit);
693 if ( file_lsn_tmp < 0 )
694 {
695 PRINTF("open fail directory %s\n", path_name);
696 SetEventFlag(g_fio_fsv_evfid, 1);
697 return -ENOENT;
698 }
699 g_cdvdman_fhinfo[i].m_file_lsn = file_lsn_tmp;
700 g_cdvdman_fhinfo[i].m_read_pos = 0;
701 g_cdvdman_fhinfo[i].m_filemode = 0;
702 g_cdvdman_fhinfo[i].m_fd_flags = 1;
703 g_cdvdman_fhinfo[i].m_fd_layer = f->unit;
704 SetEventFlag(g_fio_fsv_evfid, 1);
705 return 0;
706}
707
708static void cdvdman_fillstat(void *dummy, iox_stat_t *buf, cdvdman_filetbl_entry_t *fp)
709{
710 unsigned int i;
711
712 (void)dummy;
713
714 buf->attr = 0;
715 buf->private_5 = 0;
716 buf->private_4 = 0;
717 buf->private_3 = 0;
718 buf->private_2 = 0;
719 buf->private_1 = 0;
720 buf->private_0 = 0;
721 buf->hisize = 0;
722 for ( i = 0; i < (sizeof(buf->mtime) / sizeof(buf->mtime[0])); i += 1 )
723 {
724 buf->mtime[i] = fp->m_file_struct.date[i];
725 buf->atime[i] = fp->m_file_struct.date[i];
726 buf->ctime[i] = fp->m_file_struct.date[i];
727 }
728 buf->size = fp->m_file_struct.size;
729 buf->mode = (((fp->m_flags & 2)) ? (FIO_S_IFDIR | FIO_S_IXUSR | FIO_S_IXGRP | FIO_S_IXOTH) : FIO_S_IFREG)
731}
732
733static int cdvdman_cdfname(char *filename)
734{
735 size_t filename_len;
736
737 filename_len = strlen(filename);
738 if ( filename_len >= 3 && !(filename[filename_len - 2] != ';' && filename[filename_len - 1] != '1') )
739 {
740 return 0;
741 }
742 strcat(filename, ";1");
743 return 1;
744}
745
746static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf)
747{
748 int devready_tmp;
750 char filename[128];
751 u32 efbits;
752
753 VERBOSE_PRINTF(1, "fileIO GETSTAT name= %s layer= %d\n", name, f->unit);
754 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
755 devready_tmp = cdvdman_devready();
756 if ( devready_tmp < 0 )
757 {
758 SetEventFlag(g_fio_fsv_evfid, 1);
759 return devready_tmp;
760 }
761 strncpy(filename, name, sizeof(filename));
762 if ( !strcmp(filename, ".") )
763 {
764 strcpy(filename, "\\.");
765 }
766 if ( !strcmp(filename, "\\") )
767 {
768 strcpy(filename, "\\.");
769 }
770 if ( !strlen(filename) )
771 {
772 strcpy(filename, "\\.");
773 }
774 g_cdvdman_srchspd = 0;
775 // Unofficial: initialize to 0
776 memset(&fp, 0, sizeof(fp));
777 if (
778 !sceCdLayerSearchFile(&fp.m_file_struct, filename, f->unit)
779 && !(cdvdman_cdfname(filename) && sceCdLayerSearchFile(&fp.m_file_struct, filename, f->unit)) )
780 {
781 PRINTF("open fail name %s\n", name);
782 SetEventFlag(g_fio_fsv_evfid, 1);
783 return -ENOENT;
784 }
785 cdvdman_fillstat(filename, buf, &fp);
786 SetEventFlag(g_fio_fsv_evfid, 1);
787 return 1;
788}
789
790// cppcheck-suppress constParameterCallback
791static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf)
792{
793 int devready_tmp;
796 u32 efbits;
797
798 memset(&fp, 0, sizeof(fp));
799 VERBOSE_PRINTF(1, "fileIO DREAD\n");
800 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
801 devready_tmp = cdvdman_devready();
802 if ( devready_tmp < 0 )
803 {
804 SetEventFlag(g_fio_fsv_evfid, 1);
805 return devready_tmp;
806 }
807 fh = &g_cdvdman_fhinfo[(int)f->privdata];
808 g_cdvdman_srchspd = 0;
809 devready_tmp = sceCdReadDir(&fp.m_file_struct, fh->m_file_lsn, fh->m_read_pos, fh->m_fd_layer);
810 if ( devready_tmp < 0 )
811 {
812 SetEventFlag(g_fio_fsv_evfid, 1);
813 return -ENOENT;
814 }
815 if ( devready_tmp )
816 {
817 fh->m_read_pos += 1;
818 devready_tmp = strlen(fp.m_file_struct.name);
819 }
820 strncpy(buf->name, fp.m_file_struct.name, sizeof(buf->name));
821 cdvdman_fillstat(fp.m_file_struct.name, &buf->stat, &fp);
822 SetEventFlag(g_fio_fsv_evfid, 1);
823 return devready_tmp;
824}
825
826static int cdvd_odcinit(cdvdman_fhinfo_t *fh, int open_or_close, int id)
827{
828 int cache_remove_result;
829 int cache_result;
830 int cache_file_fd_new;
831 u32 file_size_bsr_3;
832 unsigned int file_size_bsr_17;
833 char cache_filename[512];
834 int state;
835 unsigned int ioctl_arg;
836
837 g_cdvdman_iocache = 0;
838 sprintf(
839 cache_filename,
840 "%sCache_%d_%d_%d_%d",
841 g_cdvdman_cache_name,
842 fh->m_fd_layer,
843 (int)fh->m_file_lsn,
844 (int)fh->m_file_size,
845 id);
846 cache_remove_result = 0;
847 VERBOSE_KPRINTF(1, "Cachefile:%s Open_or_Close:%d\n", cache_filename, open_or_close);
848 cache_result = 0;
849 if ( open_or_close )
850 {
851 u32 i;
852
853 CpuSuspendIntr(&state);
854 fh->m_fd_rbsize = g_cdvdman_cache_sector_size_count ? (g_cdvdman_cache_sector_size_count << 11) : 0x800;
855 fh->m_fd_rcvbuf = (u8 *)AllocSysMemory(ALLOC_LAST, fh->m_fd_rbsize, 0);
856 if ( !fh->m_fd_rcvbuf )
857 {
858 VERBOSE_KPRINTF(1, "Rcvbuf MemAlloc Fail\n");
859 CpuResumeIntr(state);
860 return -ENOMEM;
861 }
862 CpuResumeIntr(state);
863 fh->m_cache_file_fd = -1;
864 cache_result = open(cache_filename, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
865 cache_file_fd_new = cache_result;
866 if ( cache_result >= 0 )
867 {
868 u32 file_size_sectors;
869 unsigned int file_size_bsr_6;
870
871 file_size_sectors = (fh->m_file_size >> 11) + ((!!((fh->m_file_size & 0x7FF))));
872 file_size_bsr_3 = (file_size_sectors >> 3) + (!!(file_size_sectors & 7));
873 file_size_bsr_6 = (file_size_bsr_3 >> 3) + (!!((file_size_bsr_3 & 7)));
874 file_size_bsr_17 = (file_size_bsr_6 >> 11) + (!!((file_size_bsr_6 & 0x7FF)));
875 ioctl_arg = (file_size_bsr_17 + file_size_sectors + 8) << 11;
876 for ( i = 0; i < fh->m_fd_rbsize; i += 1 )
877 {
878 fh->m_fd_rcvbuf[i] = 0;
879 }
880 if ( !strncmp(cache_filename, "pfs", 3) )
881 {
882 cache_result = ioctl2(cache_file_fd_new, PIOCALLOC, &ioctl_arg, 4, 0, 0);
883 }
884 }
885 if ( cache_result >= 0 )
886 {
887 cache_result = lseek(cache_file_fd_new, 0, 0);
888 }
889 if ( cache_result >= 0 )
890 {
891 if ( !g_cdvdman_cache_sector_count )
892 __builtin_trap();
893 for ( i = 0; (int)i < (int)(g_cdvdman_cache_sector_count << 11); i += 1 )
894 {
895 ((char *)g_cdvdman_temp_buffer_ptr)[i] = 0;
896 }
897 for ( i = 0; (int)i < (int)((ioctl_arg >> 11) / g_cdvdman_cache_sector_count); i += 1 )
898 {
899 cache_result = write(cache_file_fd_new, g_cdvdman_temp_buffer_ptr, g_cdvdman_cache_sector_count << 11);
900 if ( cache_result != (g_cdvdman_cache_sector_count << 11) )
901 {
902 if ( cache_result >= 0 )
903 {
904 cache_result = -EIO;
905 }
906 break;
907 }
908 }
909 }
910 if ( cache_result >= 0 )
911 {
912 for ( i = 0; (int)i < (int)((ioctl_arg >> 11)
913 - g_cdvdman_cache_sector_count * ((ioctl_arg >> 11) / g_cdvdman_cache_sector_count));
914 i += 1 )
915 {
916 cache_result = write(cache_file_fd_new, fh->m_fd_rcvbuf, 0x800);
917 if ( cache_result != 0x800 )
918 {
919 if ( cache_result >= 0 )
920 {
921 cache_result = -EIO;
922 }
923 break;
924 }
925 }
926 }
927 }
928 if ( !open_or_close || cache_result < 0 )
929 {
930 if ( fh->m_cache_file_fd != -1 )
931 {
932 cache_remove_result = close(fh->m_cache_file_fd);
933 VERBOSE_KPRINTF(1, "Cache File Close: %d\n", cache_remove_result);
934 if ( cache_remove_result >= 0 )
935 {
936 if ( !strncmp(cache_filename, "pfs", 3) )
937 {
938 cache_remove_result = remove(cache_filename);
939 }
940 else if ( !strncmp(cache_filename, "host", 4) )
941 {
942 cache_remove_result = 0;
943 remove(cache_filename);
944 }
945 VERBOSE_KPRINTF(1, "Cache File %s remove: %d\n", cache_filename, cache_remove_result);
946 }
947 }
948 fh->m_cache_file_fd = -1;
949 fh->m_max_cluster = 0;
950 fh->m_cluster_cur = -1;
951 fh->m_sector_count_total = 0;
952 CpuSuspendIntr(&state);
953 FreeSysMemory(fh->m_fd_rcvbuf);
954 CpuResumeIntr(state);
955 fh->m_fd_rcvbuf = 0;
956 if ( cache_result < 0 )
957 {
958 VERBOSE_KPRINTF(1, "cdvd_odcinit Open Error %d\n", cache_result);
959 }
960 if ( cache_remove_result < 0 )
961 {
962 VERBOSE_KPRINTF(1, "cdvd_odcinit Close Error %d\n", cache_remove_result);
963 }
964 return (!open_or_close) ? cache_remove_result : cache_result;
965 }
966 fh->m_sector_count_total = file_size_bsr_17 << 11;
967 fh->m_cache_file_fd = cache_file_fd_new;
968 fh->m_max_cluster = (void *)file_size_bsr_3;
969 fh->m_cluster_cur = -1;
970 VERBOSE_KPRINTF(1, "Cache File Maked\n");
971 return 0;
972}
973
974static int cdvdman_cache_invalidate(cdvdman_fhinfo_t *fh, int index)
975{
976 u32 i;
977 int fileio_res;
978
979 if ( fh->m_cluster_cur == -1 )
980 {
981 return 0;
982 }
983 fh->m_cluster_cur = -1;
984 for ( i = 0; i < fh->m_fd_rbsize; i += 1 )
985 {
986 fh->m_fd_rcvbuf[i] = 0;
987 }
988 fileio_res = lseek(fh->m_cache_file_fd, 0, 0);
989 if ( fileio_res >= 0 )
990 {
991 for ( i = 0; i < ((unsigned int)fh->m_sector_count_total >> 11); i += 1 )
992 {
993 fileio_res = write(fh->m_cache_file_fd, fh->m_fd_rcvbuf, 0x800);
994 if ( fileio_res < 0 )
995 {
996 break;
997 }
998 }
999 }
1000 if ( fileio_res >= 0 )
1001 {
1002 return fileio_res;
1003 }
1004 fh->m_fd_flags &= ~4;
1005 cdvd_odcinit(fh, 0, index);
1006 return fileio_res;
1007}
1008
1009static int cdvdman_invcaches(void)
1010{
1011 unsigned int i;
1012
1013 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1014 {
1015 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 4) )
1016 {
1017 cdvdman_cache_invalidate(&g_cdvdman_fhinfo[i], i);
1018 }
1019 }
1020 return 0;
1021}
1022
1023static int cdrom_internal_cache_read(const iop_file_t *f, int nbytes)
1024{
1025 cdvdman_fhinfo_t *fh;
1026 s16 readpos_plus_nbytes;
1027 unsigned int readpos_plus_nbytes_bsr_14;
1028 int readpos_bsr_14;
1029 int cluster_cur;
1030 unsigned int i;
1031
1032 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1033 if ( cdvdman_devready() < 0 )
1034 {
1035 g_cdvdman_iocache = 0;
1036 return -EBUSY;
1037 }
1038 if ( fh->m_cluster_cur == -1 )
1039 {
1040 if ( (void *)(8 * fh->m_fd_rbsize) < fh->m_max_cluster )
1041 {
1042 fh->m_cluster_cur = (fh->m_read_pos >> 14) & ~0x7;
1043 if (
1044 lseek(fh->m_cache_file_fd, fh->m_cluster_cur >> 3, 0) < 0
1045 || read(fh->m_cache_file_fd, fh->m_fd_rcvbuf, fh->m_fd_rbsize) < 0 )
1046 {
1047 fh->m_cluster_cur = -1;
1048 return -EIO;
1049 }
1050 }
1051 else
1052 {
1053 fh->m_cluster_cur = -2;
1054 }
1055 }
1056 readpos_plus_nbytes = fh->m_read_pos + nbytes;
1057 readpos_plus_nbytes_bsr_14 = (readpos_plus_nbytes >> 14) - (!(readpos_plus_nbytes & 0x3FFF));
1058 readpos_bsr_14 = fh->m_read_pos >> 14;
1059 VERBOSE_KPRINTF(
1060 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);
1061 cluster_cur = fh->m_cluster_cur;
1062 if ( cluster_cur < 0 )
1063 {
1064 cluster_cur = 0;
1065 }
1066 else if (
1067 (unsigned int)readpos_bsr_14 < (unsigned int)cluster_cur
1068 || readpos_plus_nbytes_bsr_14 >= cluster_cur + 8 * fh->m_fd_rbsize )
1069 {
1070 int cluster_write_tmp2;
1071 unsigned int readpos_band;
1072
1073 if ( lseek(fh->m_cache_file_fd, cluster_cur >> 3, 0) < 0 )
1074 {
1075 fh->m_cluster_cur = -1;
1076 return -EIO;
1077 }
1078 cluster_write_tmp2 = (unsigned int)fh->m_max_cluster >= fh->m_cluster_cur + 8 * fh->m_fd_rbsize ?
1079 fh->m_fd_rbsize :
1080 ((unsigned int)fh->m_max_cluster - fh->m_cluster_cur + 7) >> 3;
1081 if ( write(fh->m_cache_file_fd, fh->m_fd_rcvbuf, cluster_write_tmp2) != cluster_write_tmp2 )
1082 {
1083 fh->m_cluster_cur = -1;
1084 return -EIO;
1085 }
1086 readpos_band = readpos_bsr_14 & ~0x7;
1087 fh->m_cluster_cur = readpos_band;
1088 readpos_band += (readpos_bsr_14 < 0) ? 7 : 0;
1089 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) )
1090 {
1091 fh->m_cluster_cur = -1;
1092 return -EIO;
1093 }
1094 cluster_cur = fh->m_cluster_cur;
1095 }
1096 for ( i = readpos_bsr_14; i <= readpos_plus_nbytes_bsr_14; i += 1 )
1097 {
1098 if ( !(((int)fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] >> ((i - cluster_cur) & 7)) & 1) )
1099 {
1100 break;
1101 }
1102 }
1103 return i <= readpos_plus_nbytes_bsr_14;
1104}
1105
1106static int cdrom_internal_write_cache(const iop_file_t *f, unsigned int nbytes)
1107{
1108 int lseek_result;
1109 cdvdman_fhinfo_t *fh;
1110 unsigned int cur;
1111 unsigned int rst;
1112 int cluster_cur;
1113 int write_ret;
1114 unsigned int i;
1115 int tray_open;
1116 int last_err;
1117 sceCdRMode rmode;
1118
1119 g_cdvdman_iocache = 0;
1120 if ( cdvdman_devready() < 0 )
1121 {
1122 return -EBUSY;
1123 }
1124 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1125 if ( nbytes > fh->m_file_size - fh->m_read_pos )
1126 {
1127 nbytes = fh->m_file_size - fh->m_read_pos;
1128 }
1129 if ( !nbytes )
1130 {
1131 return 0;
1132 }
1133 VERBOSE_KPRINTF(1, "_cdvdfile_cache_read %d<->%d\n", fh->m_read_pos, fh->m_read_pos + nbytes);
1134 cur = ((fh->m_read_pos + nbytes) >> 14) - (!((fh->m_read_pos + nbytes) & 0x3FFF));
1135 rst = fh->m_read_pos >> 14;
1136 cluster_cur = (fh->m_cluster_cur >= 0) ? fh->m_cluster_cur : 0;
1137 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1138 write_ret = 0;
1139 VERBOSE_KPRINTF(1, "cache_fill rst:%d<->%d cur:%d cnt:%d\n", rst, cur, fh->m_read_pos, nbytes);
1140 for ( i = rst; i <= cur; i += 1 )
1141 {
1142 VERBOSE_KPRINTF(
1143 1,
1144 "FIO Usr addr LSN:%d SEC:%d ADDR:%08x cpos= %d\n",
1145 fh->m_file_lsn + 8 * i,
1146 8,
1147 g_cdvdman_temp_buffer_ptr,
1148 (i * 0x4000) + fh->m_sector_count_total);
1149 if ( !(((int)fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] >> ((i - cluster_cur) & 7)) & 1) )
1150 {
1151 tray_open = 0;
1152 while ( !sceCdRE(fh->m_file_lsn + 8 * i, 8, g_cdvdman_temp_buffer_ptr, &rmode) )
1153 {
1154 if ( (sceCdStatus() & SCECdStatShellOpen) )
1155 {
1156 g_cdvdman_iocache = 0;
1157 tray_open = 1;
1158 break;
1159 }
1160 DelayThread(10000);
1161 }
1162 sceCdSync(0);
1163 last_err = sceCdGetError();
1164 if ( last_err != SCECdErNO || tray_open )
1165 {
1166 // The following Kprintf was modified for ioprp300x
1167 VERBOSE_KPRINTF(0, "Read Error= 0x%02x Tray open %d\n", last_err, tray_open);
1168 return -ECOMM;
1169 }
1170 lseek_result = lseek(fh->m_cache_file_fd, (i * 0x4000) + fh->m_sector_count_total, 0);
1171 if ( lseek_result < 0 )
1172 {
1173 return lseek_result;
1174 }
1175 write_ret = write(fh->m_cache_file_fd, g_cdvdman_temp_buffer_ptr, 0x4000);
1176 if ( write_ret != 0x4000 )
1177 {
1178 VERBOSE_KPRINTF(1, "write: ret:%d\n", write_ret);
1179 if ( write_ret >= 0 )
1180 {
1181 return -EIO;
1182 }
1183 break;
1184 }
1185 fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] |= 1 << ((i - cluster_cur) & 7);
1186 }
1187 }
1188 return write_ret;
1189}
1190
1191static int cdvdfile_cache_read(const iop_file_t *f, void *buf, int nbyte)
1192{
1193 int nbyte_tmp;
1194 int fd_result;
1195 cdvdman_fhinfo_t *fh;
1196
1197 if ( nbyte < 0 )
1198 {
1199 return -EINVAL;
1200 }
1201 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1202 nbyte_tmp =
1203 ((unsigned int)nbyte > fh->m_file_size - fh->m_read_pos) ? fh->m_file_size - fh->m_read_pos : (unsigned int)nbyte;
1204 VERBOSE_KPRINTF(1, "_cdvdfile_cache_read %d<->%d\n", fh->m_read_pos, fh->m_read_pos + nbyte_tmp);
1205 fd_result = 0;
1206 if ( nbyte_tmp > 0 )
1207 {
1208 fd_result = lseek(fh->m_cache_file_fd, fh->m_read_pos + fh->m_sector_count_total, 0);
1209 if ( fd_result >= 0 )
1210 {
1211 fd_result = read(fh->m_cache_file_fd, buf, nbyte_tmp);
1212 fh->m_read_pos += (fd_result >= 0) ? fd_result : 0;
1213 }
1214 }
1215 return fd_result;
1216}
1217
1218static int cdvdfile_cache_fill_read(const iop_file_t *f, void *buf, int nbytes)
1219{
1220 int op_result;
1221
1222 op_result = cdvdman_devready();
1223 if ( op_result >= 0 )
1224 {
1225 op_result = cdrom_internal_write_cache(f, nbytes);
1226 }
1227 else
1228 {
1229 g_cdvdman_iocache = 0;
1230 }
1231 if ( op_result >= 0 )
1232 {
1233 op_result = cdvdfile_cache_read(f, buf, nbytes);
1234 }
1235 return op_result;
1236}
1237
1238static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4)
1239{
1240 int fds1;
1241 unsigned int i;
1242 int emptyfdfound;
1243 int streamfdfound;
1244 cdvdman_fhinfo_t *fh;
1245 int devready_tmp;
1246 char filename[128];
1247 sceCdlFILE fp;
1248 u32 efbits;
1249
1250 (void)arg4;
1251 devready_tmp = 0;
1252 fds1 = 0;
1253 VERBOSE_PRINTF(1, "fileIO OPEN name= %s mode= 0x%08x layer %d\n", name, mode, f->unit);
1254 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1255 emptyfdfound = 0;
1256 streamfdfound = 0;
1257 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1258 {
1259 if ( !g_cdvdman_fhinfo[i].m_fd_flags && !emptyfdfound )
1260 {
1261 fds1 = i;
1262 emptyfdfound = 1;
1263 }
1264 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 8) )
1265 {
1266 streamfdfound = 1;
1267 }
1268 }
1269 if ( !emptyfdfound || streamfdfound )
1270 {
1271 PRINTF("open fail name %s\n", name);
1272 SetEventFlag(g_fio_fsv_evfid, 1);
1273 return -EMFILE;
1274 }
1275 f->privdata = (void *)fds1;
1276 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1277 strncpy(filename, name, sizeof(filename));
1278 cdvdman_cdfname(filename);
1279 g_cdvdman_srchspd = (!(mode & 0x40000000) && !cdvdman_l0check(f->unit)) ?
1280 ((g_cdvdman_spinnom == -1) ? (u16)mode : g_cdvdman_spinnom != SCECdSpinStm) :
1281 0;
1282 if ( (unsigned int)(f->unit) >= 2u )
1283 {
1284 devready_tmp = -ENOENT;
1285 }
1286 else
1287 {
1288 if ( !strncmp(name, "sce_cdvd_lsn", 12) )
1289 {
1290 strncpy(filename, name, sizeof(filename));
1291 // Unofficial: Avoid out of bounds access
1292 for ( i = 12; i < (sizeof(filename) - 5) && filename[i] && filename[i] != '_'; i += 1 )
1293 ;
1294 if ( !filename[i] || i >= (sizeof(filename) - 5) )
1295 {
1296 devready_tmp = -ENOENT;
1297 }
1298 else
1299 {
1300 fp.size = strtol(&filename[i + 5], 0, 10);
1301 filename[i] = 0;
1302 fp.lsn = strtol(&filename[12], 0, 10);
1303 if ( f->unit )
1304 {
1305 if ( cdvdman_devready() < 0 || !DvdDual_infochk() )
1306 {
1307 devready_tmp = -ENOENT;
1308 }
1309 else
1310 {
1311 fp.lsn += g_cdvdman_istruct.m_layer_1_lsn;
1312 }
1313 }
1314 }
1315 }
1316#ifdef CDVD_VARIANT_OSD
1317 else if ( !strcmp(filename, "sce_dev5;1") )
1318 {
1319 fp.lsn = -1;
1320 fp.size = 0;
1321 }
1322#endif
1323 else
1324 {
1325 devready_tmp = cdvdman_devready();
1326 if ( devready_tmp < 0 )
1327 {
1328 SetEventFlag(g_fio_fsv_evfid, 1);
1329 return devready_tmp;
1330 }
1331 if ( !sceCdLayerSearchFile(&fp, filename, f->unit) )
1332 {
1333 devready_tmp = -ENOENT;
1334 }
1335 }
1336 }
1337 if ( devready_tmp < 0 )
1338 {
1339 PRINTF("open fail name %s\n", filename);
1340 SetEventFlag(g_fio_fsv_evfid, 1);
1341 return devready_tmp;
1342 }
1343 fh->m_fd_flags = 1;
1344 g_cdvdman_srchspd = 0;
1345 if ( (mode & 0x40000000) )
1346 {
1347 sceCdRMode rmode;
1348 memset(&rmode, 0, sizeof(rmode));
1349 rmode.datapattern = SCECdSecS2048;
1350 rmode.spindlctrl = SCECdSpinStm;
1351 rmode.trycount = (g_cdvdman_trycnt != -1) ? g_cdvdman_trycnt : 0;
1352 // The following call to sceCdStStart was inlined
1353 if ( !sceCdStStart(fp.lsn, &rmode) )
1354 {
1355 fh->m_fd_flags = 0;
1356 SetEventFlag(g_fio_fsv_evfid, 1);
1357 return -ENOENT;
1358 }
1359 g_cdvdman_strmerr = 0;
1360 fh->m_fd_flags |= 8;
1361 }
1362 fh->m_file_lsn = fp.lsn;
1363 fh->m_read_pos = 0;
1364 fh->m_filemode = mode & ~0x40000000;
1365 fh->m_file_size = fp.size;
1366 fh->m_fd_layer = f->unit;
1367 if ( (mode & 0x50000000) == 0x10000000 )
1368 {
1369 devready_tmp = -ENODEV;
1370 if ( g_cache_path_fd != -1 )
1371 {
1372 devready_tmp = cdvd_odcinit(fh, 1, (int)f->privdata);
1373 if ( devready_tmp >= 0 )
1374 {
1375 fh->m_fd_flags |= 4;
1376 }
1377 }
1378 }
1379 if ( devready_tmp < 0 )
1380 {
1381 fh->m_fd_flags = 0;
1382 fh->m_fd_layer = 0;
1383 fh->m_filemode = 0;
1384 fh->m_read_pos = 0;
1385 fh->m_file_size = 0;
1386 fh->m_file_lsn = 0;
1387 SetEventFlag(g_fio_fsv_evfid, 1);
1388 return devready_tmp;
1389 }
1390 f->mode = O_RDONLY;
1391 // The following Kprintf was added for ioprp300x
1392 VERBOSE_KPRINTF(1, "open end file_lbn= %d size= %d fds= %d\n", fh->m_file_lsn, fh->m_file_size, fds1);
1393 SetEventFlag(g_fio_fsv_evfid, 1);
1394 return 0;
1395}
1396
1397static int cdrom_close(iop_file_t *f)
1398{
1399 cdvdman_fhinfo_t *fh;
1400 u32 efbits;
1401
1402 VERBOSE_PRINTF(1, "fileIO CLOSE\n");
1403 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1404 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1405 if ( (fh->m_fd_flags & 8) )
1406 {
1407 g_cdvdman_strmerr = 0;
1408 // The following call to sceCdStStop was inlined
1409 if ( !sceCdStStop() )
1410 {
1411 SetEventFlag(g_fio_fsv_evfid, 1);
1412 return -EIO;
1413 }
1414 }
1415 if ( ((fh->m_fd_flags & 0xC) == 4 && cdvd_odcinit(fh, 0, (int)f->privdata) < 0) )
1416 {
1417 SetEventFlag(g_fio_fsv_evfid, 1);
1418 return -EIO;
1419 }
1420 fh->m_file_lsn = 0;
1421 fh->m_file_size = 0;
1422 fh->m_read_pos = 0;
1423 fh->m_fd_flags = 0;
1424 fh->m_fd_layer = 0;
1425 fh->m_filemode = 1;
1426 f->mode = 0;
1427 SetEventFlag(g_fio_fsv_evfid, 1);
1428 return 0;
1429}
1430
1431static int cdrom_internal_read(const iop_file_t *f, char *addr, int nbytes)
1432{
1433 unsigned int sectors;
1434 int op_result;
1435 int nbytes_segment;
1436 int nbytes_div_2048;
1437 unsigned int sec;
1438 unsigned int sectors_count;
1439 int last_err;
1440 sceCdRMode rmode;
1441 int i;
1442 unsigned int filesize_bsr_11;
1443 cdvdman_fhinfo_t *fh;
1444 void *buf;
1445
1446 sectors = 1;
1447 VERBOSE_PRINTF(1, "cdvd fileIO read start\n");
1448 op_result = cdvdman_devready();
1449 if ( op_result < 0 )
1450 {
1451 g_cdvdman_iocache = 0;
1452 return op_result;
1453 }
1454 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1455 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1456 if ( nbytes < 0 )
1457 {
1458 return -EINVAL;
1459 }
1460 if ( (unsigned int)nbytes > fh->m_file_size - fh->m_read_pos )
1461 {
1462 nbytes = fh->m_file_size - fh->m_read_pos;
1463 }
1464 filesize_bsr_11 = (fh->m_file_size >> 11) + (!!((fh->m_file_size & 0x7FF))) + fh->m_file_lsn;
1465 VERBOSE_PRINTF(
1466 1, "fds= %d read file_lbn= %d offset= %d\n", (int)(uiptr)f->privdata, (int)fh->m_file_lsn, (int)fh->m_read_pos);
1467 buf = 0;
1468 for ( i = 0; i < nbytes; i += nbytes_segment )
1469 {
1470 unsigned int lbn;
1471 int pos_extra;
1472 int lbn_tmp;
1473 int pos_sub_2048;
1474 int nbytes_cur;
1475
1476 nbytes_cur = nbytes - i;
1477 if ( g_cdvdman_spinctl != -1 )
1478 {
1479 rmode.spindlctrl = g_cdvdman_spinctl;
1480 switch ( g_cdvdman_spinctl )
1481 {
1482 case SCECdSpinStm:
1483 fh->m_filemode = 0;
1484 break;
1485 case SCECdSpinNom:
1486 fh->m_filemode = 1;
1487 break;
1488 case SCECdSpinX1:
1489 fh->m_filemode = 2;
1490 break;
1491 case SCECdSpinX2:
1492 fh->m_filemode = 3;
1493 break;
1494 case SCECdSpinX4:
1495 fh->m_filemode = 4;
1496 break;
1497 case SCECdSpinX12:
1498 fh->m_filemode = 5;
1499 break;
1500 default:
1501 fh->m_filemode = 1;
1502 break;
1503 }
1504 }
1505 pos_sub_2048 = 0;
1506 lbn = fh->m_file_lsn + ((fh->m_read_pos + i) >> 11);
1507 lbn_tmp = lbn;
1508 pos_extra = (fh->m_read_pos + i) & 0x7FF;
1509 if ( nbytes_cur <= 0x4000 )
1510 {
1511 nbytes_segment = nbytes_cur;
1512 nbytes_div_2048 = (nbytes_cur / 0x800) + (!!((nbytes_cur & 0x7FF)));
1513 sectors = nbytes_div_2048 + (!!pos_extra);
1514 }
1515 else
1516 {
1517 nbytes_segment = 0x4000;
1518 if ( buf && ((fh->m_read_pos + i) & 0x7FF) && g_cdvdman_iocache )
1519 {
1520 lbn += 1;
1521 pos_sub_2048 = 0x800 - pos_extra;
1522 optimized_memcpy(
1523 &addr[i], &((const char *)g_cdvdman_temp_buffer_ptr)[0x800 * (sectors - 1) + pos_extra], 0x800 - pos_extra);
1524 g_cdvdman_iocache = 0;
1525 sectors = 8;
1526 }
1527 else
1528 {
1529 sectors = 8 + (!!(((fh->m_read_pos + i) & 0x7FF)));
1530 }
1531 }
1532 buf = g_cdvdman_temp_buffer_ptr;
1533 if ( (unsigned int)(sectors) > filesize_bsr_11 - lbn )
1534 {
1535 sectors = filesize_bsr_11 - lbn;
1536 }
1537 VERBOSE_PRINTF(1, "sce_Read LBN= %d sectors= %d\n", (int)lbn, (int)sectors);
1538 if (
1539 g_cdvdman_iocache && (lbn >= g_cdvdman_lcn_offset)
1540 && (g_cdvdman_lcn_offset + g_cdvdman_numbytes_offset >= lbn + sectors) )
1541 {
1542 optimized_memcpy(&addr[i], &((char *)buf)[0x800 * (lbn - g_cdvdman_lcn_offset) + pos_extra], nbytes_segment);
1543 }
1544 else if ( ((uiptr)(addr + i) & 3) || pos_extra || (nbytes_segment != 0x4000) )
1545 {
1546 sec = (sectors >= 8) ? sectors : 8;
1547 if ( sec > filesize_bsr_11 - lbn )
1548 {
1549 sec = filesize_bsr_11 - lbn;
1550 }
1551 VERBOSE_PRINTF(1, "FIO Cache LSN:%d SEC:%d ADDR:%08x\n", (int)lbn, (int)sec, (unsigned int)(uiptr)buf);
1552 sectors_count = (sec >= 9) ? (sec - 8) : 0;
1553 if ( sectors_count )
1554 {
1555 while ( !sceCdRE(lbn, sectors_count, buf, &rmode) )
1556 {
1557 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1558 if ( (sceCdStatus() & SCECdStatShellOpen) )
1559 {
1560 g_cdvdman_iocache = 0;
1561 g_cdvdman_spinctl = -1;
1562 return -EIO;
1563 }
1564 DelayThread(10000);
1565 }
1566 sceCdSync(0);
1567 last_err = sceCdGetError();
1568 if ( last_err != SCECdErNO )
1569 {
1570 PRINTF("Read Error= 0x%02x\n", last_err);
1571 g_cdvdman_iocache = 0;
1572 break;
1573 }
1574 }
1575 while ( !sceCdRE(lbn + sectors_count, sec - sectors_count, (char *)buf + 0x800 * sectors_count, &rmode) )
1576 {
1577 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1578 if ( (sceCdStatus() & SCECdStatShellOpen) )
1579 {
1580 g_cdvdman_iocache = 0;
1581 g_cdvdman_spinctl = -1;
1582 return -EIO;
1583 }
1584 DelayThread(10000);
1585 }
1586 sceCdSync(0);
1587 last_err = sceCdGetError();
1588 if ( last_err != SCECdErNO )
1589 {
1590 PRINTF("Read Error= 0x%02x\n", last_err);
1591 g_cdvdman_iocache = 0;
1592 break;
1593 }
1594 g_cdvdman_lcn_offset = lbn_tmp;
1595 g_cdvdman_numbytes_offset = sec;
1596 g_cdvdman_iocache = 1;
1597 optimized_memcpy(
1598 &addr[pos_sub_2048 + i],
1599 &((const char *)g_cdvdman_temp_buffer_ptr)[!pos_sub_2048 ? pos_extra : 0],
1600 nbytes_segment - pos_sub_2048);
1601 }
1602 else
1603 {
1604 VERBOSE_PRINTF(
1605 1, "FIO Usr addr LSN:%d SEC:%d ADDR:%08x\n", (int)lbn, (int)sectors, (unsigned int)(uiptr)(addr + i));
1606 while ( !sceCdRE(lbn, sectors, addr + i, &rmode) )
1607 {
1608 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1609 if ( (sceCdStatus() & SCECdStatShellOpen) )
1610 {
1611 g_cdvdman_iocache = 0;
1612 g_cdvdman_spinctl = -1;
1613 return -EIO;
1614 }
1615 DelayThread(10000);
1616 }
1617 sceCdSync(0);
1618 last_err = sceCdGetError();
1619 g_cdvdman_iocache = 0;
1620 if ( last_err != SCECdErNO )
1621 {
1622 PRINTF("Read Error= 0x%02x\n", last_err);
1623 break;
1624 }
1625 }
1626 if ( nbytes_segment <= 0 )
1627 {
1628 g_cdvdman_spinctl = -1;
1629 return nbytes_segment;
1630 }
1631 }
1632 fh->m_read_pos += i;
1633 VERBOSE_PRINTF(1, "fileIO read ended\n");
1634 g_cdvdman_spinctl = -1;
1635 return i;
1636}
1637
1638static int cdrom_stream_read(const iop_file_t *f, char *bbuf, int nbytes)
1639{
1640 cdvdman_fhinfo_t *fh;
1641 sceCdRMode rmode;
1642 int buf;
1643
1644 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1645 g_cdvdman_strmerr = 0;
1646 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1647 rmode.spindlctrl = SCECdSpinStm;
1648 rmode.trycount = 0;
1649 // The following sceCdStRead call was inlined
1650 buf = sceCdStRead(nbytes >> 11, (u32 *)bbuf, STMNBLK, (u32 *)&g_cdvdman_strmerr);
1651 fh->m_read_pos += buf << 11;
1652 return buf << 11;
1653}
1654
1655// cppcheck-suppress constParameterCallback
1656static int cdrom_read(iop_file_t *f, void *buf, int nbytes)
1657{
1658 cdvdman_fhinfo_t *fh;
1659 int rc;
1660 u32 efbits;
1661
1662 if ( nbytes < 0 )
1663 {
1664 return -EINVAL;
1665 }
1666 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1667 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1668 if ( cdvdman_mediactl(2) )
1669 {
1670 g_cdvdman_iocache = 0;
1671 cdvdman_invcaches();
1672 }
1673 if ( (fh->m_fd_flags & 8) )
1674 {
1675 rc = cdrom_stream_read(f, (char *)buf, nbytes);
1676 }
1677 else
1678 {
1679 if ( !(fh->m_fd_flags & 4) )
1680 {
1681 rc = cdrom_internal_read(f, (char *)buf, nbytes);
1682 }
1683 else
1684 {
1685 rc = cdrom_internal_cache_read(f, nbytes);
1686 if ( rc )
1687 {
1688 if ( rc != -EBUSY )
1689 {
1690 if ( rc != 1 )
1691 {
1692 fh->m_fd_flags &= ~4;
1693 rc = -EIO;
1694 cdvd_odcinit(fh, 0, (int)f->privdata);
1695 }
1696 else
1697 {
1698 rc = cdvdfile_cache_fill_read(f, buf, nbytes);
1699 VERBOSE_KPRINTF(1, "called _cdvdfile_cache_fill_read %d\n", rc);
1700 }
1701 }
1702 }
1703 else
1704 {
1705 rc = cdvdfile_cache_read(f, buf, nbytes);
1706 VERBOSE_KPRINTF(1, "called _cdvdfile_cache_read %d\n", rc);
1707 }
1708 if ( rc == -EBUSY || rc == -ECOMM )
1709 {
1710 cdvdman_cache_invalidate(fh, (int)f->privdata);
1711 KPRINTF("_cdvdfile_cache Read_err OR Drive_not_ready\n", rc);
1712 }
1713 if ( rc < 0 )
1714 {
1715 rc = cdrom_internal_read(f, (char *)buf, nbytes);
1716 }
1717 }
1718 }
1719 SetEventFlag(g_fio_fsv_evfid, 1);
1720 return rc;
1721}
1722
1723static int cdrom_ioctl(iop_file_t *f, int arg, void *param)
1724{
1725#ifdef CDVD_VARIANT_OSD
1726 USE_IOP_MMIO_HWPORT();
1727#endif
1728
1729 (void)f;
1730
1731 switch ( arg )
1732 {
1733#ifdef CDVD_VARIANT_OSD
1734 case 0x6310:
1735 return mfc0(PRID);
1736 case 0x6311:
1737 if ( mfc0(PRID) < 35 )
1738 {
1739 return -22;
1740 }
1741 if ( *(u32 *)param )
1742 {
1743 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] |= 1;
1744 }
1745 else
1746 {
1747 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] &= ~1;
1748 }
1749 return 0;
1750 case 0x6312:
1751 return mfc0(PRID) >= 35 ? (int)(/* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] & 1) : -22;
1752#endif
1753 case 0x10000:
1754 g_cdvdman_spinnom = -1;
1755 sceCdSpinCtrlIOP((u32)param);
1756 return 0;
1757#ifdef CDVD_VARIANT_OSD
1758 case 0x10008:
1759 sceCdDecSet(*(u32 *)param, *((u32 *)param + 1), *((u32 *)param + 2));
1760 return 0;
1761 case 0x10020:
1762 return sceCdReadKey(*(u32 *)param, *((u32 *)param + 1), *((u32 *)param + 2), (u8 *)param + 12) ? 1 : -16;
1763 case 0x10030:
1764 return sceCdGetDiskType();
1765#endif
1766 default:
1767 return -EIO;
1768 }
1769}
1770
1771// cppcheck-suppress constParameterCallback
1772static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen)
1773{
1774 const cdvdman_fhinfo_t *fh;
1775 int retval;
1776 u32 efbits;
1777
1778 (void)argp;
1779 (void)arglen;
1780 (void)bufp;
1781 (void)buflen;
1782
1783 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1784 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1785 retval = -EIO;
1786 if ( (fh->m_fd_flags & 8) )
1787 {
1788 switch ( request )
1789 {
1790 case CIOCSTREAMPAUSE:
1791 // The following call to sceCdStPause was inlined
1792 if ( sceCdStPause() )
1793 {
1794 retval = 0;
1795 }
1796 break;
1797 case CIOCSTREAMRESUME:
1798 // The following call to sceCdStResume was inlined
1799 if ( sceCdStResume() )
1800 {
1801 retval = 0;
1802 }
1803 break;
1804 case CIOCSTREAMSTAT:
1805 // The following call to sceCdStStat was inlined
1806 // Unofficial: return 0 instead of negative value
1807 retval = sceCdStStat();
1808 break;
1809 default:
1810 break;
1811 }
1812 }
1813 SetEventFlag(g_fio_fsv_evfid, 1);
1814 return retval;
1815}
1816
1817static int
1818cdrom_devctl(iop_file_t *f, const char *name, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen)
1819{
1820 unsigned int i;
1821 int retval2;
1822 char *sc_tmp_2;
1823 unsigned int sc_tmp_3;
1824 u32 efbits;
1825 int on_dual_tmp;
1826 int scres_unused;
1827
1828 (void)f;
1829 (void)name;
1830 (void)buflen;
1831
1832 retval2 = 0;
1833 if ( cmd != CDIOC_BREAK )
1834 {
1835 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1836 }
1837 switch ( cmd )
1838 {
1839 case CDIOC_READCLOCK:
1840 for ( i = 0; i < 3 && !retval2; i += 1 )
1841 {
1842 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1843 retval2 = sceCdReadClock((sceCdCLOCK *)bufp);
1844 }
1845 retval2 = (retval2 != 1) ? -EIO : 0;
1846 break;
1847#ifdef CDVD_VARIANT_DNAS
1848 case 0x431D:
1849 for ( i = 0; i < 3 && !retval2; i += 1 )
1850 {
1851 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1852 retval2 = sceCdReadGUID((u64 *)bufp);
1853 }
1854 retval2 = (retval2 != 1) ? -EIO : 0;
1855 break;
1856 case 0x431E:
1857 retval2 = (sceCdReadDiskID((unsigned int *)bufp) != 1) ? -EIO : 0;
1858 break;
1859#endif
1860 case CDIOC_GETDISKTYP:
1861 *(u32 *)bufp = sceCdGetDiskType();
1862 break;
1863 case CDIOC_GETERROR:
1864 *(u32 *)bufp = g_cdvdman_strmerr ? g_cdvdman_strmerr : sceCdGetError();
1865 break;
1866 case CDIOC_TRAYREQ:
1867 retval2 = (sceCdTrayReq(*(u32 *)argp, (u32 *)bufp) != 1) ? -EIO : 0;
1868 break;
1869 case CDIOC_STATUS:
1870 *(u32 *)bufp = sceCdStatus();
1871 break;
1872 case CDIOC_POWEROFF:
1873 for ( i = 0; i < 3 && !retval2; i += 1 )
1874 {
1875 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1876 retval2 = sceCdPowerOff((u32 *)bufp);
1877 }
1878 retval2 = (retval2 != 1) ? -EIO : 0;
1879 break;
1880 case CDIOC_MMODE:
1881 sceCdMmode(*(u32 *)argp);
1882 break;
1883 case CDIOC_DISKRDY:
1884 *(u32 *)bufp = sceCdDiskReady(*(u32 *)argp);
1885 break;
1886#ifdef CDVD_VARIANT_DNAS
1887 case 0x4326:
1888 for ( i = 0; i < 3 && !retval2; i += 1 )
1889 {
1890 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1891 retval2 = sceCdReadModelID((unsigned int *)bufp);
1892 }
1893 retval2 = (retval2 != 1) ? -EIO : 0;
1894 break;
1895#endif
1896 case CDIOC_STREAMINIT:
1897 // The following call to sceCdStInit was inlined
1898 retval2 = (!sceCdStInit(*(u32 *)argp, *((u32 *)argp + 1), (void *)*((u32 *)argp + 2))) ? -EIO : 0;
1899 break;
1900 case CDIOC_BREAK:
1901 retval2 = (!sceCdBreak()) ? -EIO : 0;
1902 sceCdSync(4);
1903 break;
1904#ifdef CDVD_VARIANT_XOSD
1905 case 0x437F:
1906 sc_tmp_3 = *(u32 *)argp;
1907 retval2 = (sc_tmp_3 - 4 >= 0x15) ? -22 : sceCdSC(0xFFFFFFDD, (int *)&sc_tmp_3);
1908 break;
1909#endif
1910 case CDIOC_SPINNOM:
1911 g_cdvdman_spinnom = SCECdSpinNom;
1912 break;
1913 case CDIOC_SPINSTM:
1914 g_cdvdman_spinnom = SCECdSpinStm;
1915 break;
1916 case CDIOC_TRYCNT:
1917 g_cdvdman_trycnt = *(u8 *)argp;
1918 break;
1919 case 0x4383:
1920 retval2 = (sceCdSeek(*(u32 *)argp) != 1) ? -EIO : 0;
1921 sceCdSync(6);
1922 break;
1923 case CDIOC_STANDBY:
1924 retval2 = (sceCdStandby() != 1) ? -EIO : 0;
1925 sceCdSync(4);
1926 break;
1927 case CDIOC_STOP:
1928 retval2 = (sceCdStop() != 1) ? -EIO : 0;
1929 sceCdSync(4);
1930 break;
1931 case CDIOC_PAUSE:
1932 retval2 = (sceCdPause() != 1) ? -EIO : 0;
1933 sceCdSync(6);
1934 break;
1935 case CDIOC_GETTOC:
1936 switch ( sceCdGetDiskType() )
1937 {
1938 case SCECdPSCD:
1939 case SCECdPSCDDA:
1940 case SCECdPS2CD:
1941 case SCECdPS2CDDA:
1942 retval2 = (sceCdGetToc((u8 *)bufp) != 1) ? -EIO : 0;
1943 break;
1944 default:
1945 break;
1946 }
1947 break;
1948 case CDIOC_SETTIMEOUT:
1949 retval2 = (sceCdSetTimeout(1, *(u32 *)argp) != 1) ? -EIO : 0;
1950 break;
1951 case CDIOC_READDVDDUALINFO:
1952 retval2 = (!sceCdReadDvdDualInfo(&on_dual_tmp, (unsigned int *)bufp)) ? -EIO : 0;
1953 break;
1954 case CDIOC_INIT:
1955 sceCdInit(*(u32 *)argp);
1956 retval2 = 0;
1957 break;
1958 case 0x438C:
1959 g_cdvdman_spinnom = SCECdSpinX1;
1960 break;
1961 case 0x438D:
1962 g_cdvdman_spinnom = SCECdSpinX2;
1963 break;
1964 case 0x438E:
1965 g_cdvdman_spinnom = SCECdSpinX4;
1966 break;
1967 case 0x438F:
1968 g_cdvdman_spinnom = SCECdSpinX12;
1969 break;
1970 case 0x4390:
1971 g_cdvdman_spinnom = SCECdSpinMx;
1972 break;
1973 case 0x4391:
1974 *(u32 *)bufp = sceCdSC(0xFFFFFFF5, &scres_unused);
1975 break;
1976 case 0x4392:
1977 retval2 = (sceCdApplySCmd(*(u8 *)argp, (char *)argp + 4, arglen - 4, bufp) != 1) ? -EIO : 0;
1978 break;
1979 case CDIOC_FSCACHEINIT:
1980 retval2 = -EBUSY;
1981 if ( g_cache_path_fd != -1 )
1982 {
1983 break;
1984 }
1985 retval2 = -EINVAL;
1986 sc_tmp_2 = (char *)argp;
1987 for ( i = 0; i < arglen && sc_tmp_2[i] && sc_tmp_2[i] != ','; i += 1 )
1988 {
1989 g_cdvdman_cache_name[i] = sc_tmp_2[i];
1990 }
1991 sc_tmp_3 = i;
1992 if ( i <= arglen )
1993 {
1994 i += 1;
1995 for ( ; (i < arglen) && sc_tmp_2[i] && sc_tmp_2[i] != ','; i += 1 )
1996 {
1997 }
1998 }
1999 if ( i <= arglen )
2000 {
2001 sc_tmp_2[i] = 0;
2002 g_cdvdman_cache_sector_size_count = strtol((const char *)argp + sc_tmp_3, 0, 10);
2003 retval2 = path_tbl_init(strtol(&sc_tmp_2[i + 1], 0, 10), g_cdvdman_cache_name, 1);
2004 }
2005 break;
2006 case CDIOC_FSCACHEDELETE:
2007 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
2008 {
2009 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 4) )
2010 {
2011 break;
2012 }
2013 }
2014 retval2 = (i == (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0]))) ? path_tbl_init(0, 0, 0) : -EBUSY;
2015 break;
2016 default:
2017 retval2 = -EIO;
2018 break;
2019 }
2020 if ( cmd != CDIOC_BREAK )
2021 {
2022 SetEventFlag(g_fio_fsv_evfid, 1);
2023 }
2024 return retval2;
2025}
2026
2027// cppcheck-suppress constParameterCallback
2028static int cdrom_lseek(iop_file_t *f, int offset, int pos)
2029{
2030 int retval;
2031 cdvdman_fhinfo_t *fh;
2032 u32 efbits;
2033
2034 retval = -EPERM;
2035 VERBOSE_PRINTF(1, "fileIO SEEK\n");
2036 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
2037 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
2038 switch ( pos )
2039 {
2040 case 0:
2041 retval = offset;
2042 break;
2043 case 1:
2044 retval = fh->m_read_pos + offset;
2045 break;
2046 case 2:
2047 retval = fh->m_file_size - offset;
2048 break;
2049 default:
2050 break;
2051 }
2052 if ( retval > (int)(fh->m_file_size) )
2053 {
2054 retval = fh->m_file_size;
2055 }
2056 fh->m_read_pos = retval;
2057 if ( (fh->m_fd_flags & 8) )
2058 {
2059 // The following call to sceCdStSeekF was inlined
2060 if ( !sceCdStSeekF(fh->m_file_lsn + retval / 0x800) )
2061 {
2062 retval = -EIO;
2063 }
2064 }
2065 SetEventFlag(g_fio_fsv_evfid, 1);
2066 return retval;
2067}
2068
2069static int sync_timeout_alarm_cb(const iop_sys_clock_t *sys_clock)
2070{
2071 KPRINTF("Cdvd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
2072 return !sceCdBreak();
2073}
2074
2075int sceCdSetTimeout(int param, int timeout)
2076{
2077 if ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2078 {
2079 return 0;
2080 }
2081 switch ( param )
2082 {
2083 case 1:
2084 g_cdvdman_sync_timeout = timeout;
2085 return 1;
2086 case 2:
2087 g_cdvdman_stream_timeout = timeout;
2088 return 1;
2089 default:
2090 return 0;
2091 }
2092}
2093
2094int sceCdSync(int mode)
2095{
2096 iop_sys_clock_t sysclk;
2097 iop_event_info_t efinfo;
2098 u32 efbits;
2099
2100 VERBOSE_KPRINTF(1, "sceCdSync: Call mode %d Com %x\n", mode, (u8)g_cdvdman_istruct.m_cdvdman_command);
2101 switch ( mode )
2102 {
2103 case 0:
2104 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2105 {
2106 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2107 }
2108 break;
2109 case 1:
2110 return !!(!sceCdCheckCmd() || (g_cdvdman_istruct.m_read2_flag));
2111 case 3:
2112 sysclk.hi = 0;
2113 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
2114 vSetAlarm(&sysclk, (unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
2115 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2116 {
2117 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2118 }
2119 vCancelAlarm((unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
2120 break;
2121 case 4:
2122 sysclk.hi = 0;
2123 sysclk.lo = 0x41EB0000;
2124 vSetAlarm(&sysclk, (unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
2125 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2126 {
2127 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2128 }
2129 vCancelAlarm((unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
2130 break;
2131 case 5:
2132 while ( !sceCdCheckCmd() )
2133 {
2134 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2135 }
2136 break;
2137 case 6:
2138 sysclk.hi = 0;
2139 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
2140 vSetAlarm(&sysclk, (unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
2141 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2142 {
2143 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2144 }
2145 vCancelAlarm((unsigned int (*)(void *))sync_timeout_alarm_cb, &sysclk);
2146 break;
2147 case 16:
2148 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2149 || g_cdvdman_istruct.m_stream_flag )
2150 {
2151 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2152 if ( g_cdvdman_ee_rpc_fno )
2153 {
2154 DelayThread(8000);
2155 }
2156 }
2157 break;
2158 case 17:
2159 return !!(
2160 !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2161 || (g_cdvdman_istruct.m_stream_flag));
2162 case 32:
2163 WaitEventFlag(g_cdvdman_intr_evfid, 0x21, WEF_OR, &efbits);
2164 ReferEventFlagStatus(g_cdvdman_intr_evfid, &efinfo);
2165 if ( !(efinfo.currBits & 0x20) )
2166 {
2167 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
2168 {
2169 SetEventFlag(g_cdvdman_intr_evfid, 0x20);
2170 }
2171 else
2172 {
2173 WaitEventFlag(g_cdvdman_intr_evfid, 0x20, WEF_AND, &efbits);
2174 }
2175 }
2176 break;
2177 default:
2178 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2179 {
2180 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2181 }
2182 break;
2183 }
2184 VERBOSE_KPRINTF(
2185 1,
2186 "sceCdSync: Command= %d Error= %d\n",
2187 (u8)g_cdvdman_istruct.m_cdvdman_command,
2188 (u8)g_cdvdman_istruct.m_last_error);
2189 return 0;
2190}
2191
2192int sceCdSpinCtrlIOP(u32 speed)
2193{
2194 VERBOSE_KPRINTF(1, "sceCdSpinCtrlIOP speed= %d\n", speed);
2195 g_cdvdman_spinctl = speed;
2196 return 1;
2197}
2198
2199int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
2200{
2201 unsigned int i;
2202 int search_res;
2203 u32 efbits;
2204
2205 if ( PollEventFlag(g_sfile_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
2206 {
2207 return 0;
2208 }
2209 for ( i = 0; i < ((sizeof(g_cdvdman_sfname) / sizeof(g_cdvdman_sfname[0])) - 1) && path[i]; i += 1 )
2210 {
2211 g_cdvdman_sfname[i] = path[i];
2212 }
2213 g_cdvdman_sfname[i] = 0;
2214 g_cdvdman_srchspd = 1;
2215 search_res = CdSearchFileInner((cdvdman_filetbl_entry_t *)fp, g_cdvdman_sfname, layer);
2216 vSetEventFlag(g_sfile_evfid, 1);
2217 return search_res;
2218}
2219
2220int sceCdSearchFile(sceCdlFILE *file, const char *name)
2221{
2222 return sceCdLayerSearchFile(file, name, 0);
2223}
2224
2225int sceCdGetToc(u8 *toc)
2226{
2227 return cdvdman_gettoc(toc);
2228}
2229
2230int sceCdDiskReady(int mode)
2231{
2232 u32 efbits;
2233 USE_DEV5_MMIO_HWPORT();
2234
2235 efbits = 0;
2236 // The following Kprintf was modified for ioprp300x
2237 VERBOSE_KPRINTF(1, "DISK READY call from iop %d\n", mode);
2238#ifdef CDVD_VARIANT_XOSD
2239 if ( g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1 )
2240 {
2241 return mode == 8 ? -1 : 6;
2242 }
2243 switch ( get_disk_type_ex() )
2244 {
2245 case SCECdNODISC:
2246 case 257:
2247 return 2;
2248 default:
2249 break;
2250 }
2251#endif
2252 switch ( mode )
2253 {
2254 case 0:
2255 VERBOSE_KPRINTF(1, "Wait Drive Ready %x\n", dev5_mmio_hwport->m_dev5_reg_005);
2256 while ( g_cdvdman_istruct.m_read2_flag )
2257 {
2258 // The following call to sceCdGetDiskType was inlined
2259#ifdef CDVD_VARIANT_XOSD
2260 switch ( get_disk_type_ex() )
2261#else
2262 switch ( sceCdGetDiskType() )
2263#endif
2264 {
2265 case SCECdDETCT:
2266 case SCECdDETCTCD:
2267 case SCECdDETCTDVDS:
2268 case SCECdDETCTDVDD:
2269 while ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) != 0x40 )
2270 {
2271 vDelayThread(2000);
2272 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2273#ifdef CDVD_VARIANT_XOSD
2274 if ( !get_disk_type_ex() )
2275 {
2276 return 2;
2277 }
2278#endif
2279 }
2280 continue;
2281 default:
2282 break;
2283 }
2284 break;
2285 }
2286 // The following Kprintf was added for ioprp300x
2287 VERBOSE_KPRINTF(1, "Wait Exit\n");
2288 return 2;
2289 case 8:
2290 return (u8)dev5_mmio_hwport->m_dev5_reg_005;
2291 case 1:
2292 default:
2293 if ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag )
2294 {
2295 return 2;
2296 }
2297 VERBOSE_KPRINTF(1, "Drive Not Ready\n");
2298 return 6;
2299 }
2300}
2301
2302int sceCdGetDiskType(void)
2303{
2304#ifdef CDVD_VARIANT_XOSD
2305 int cdvd_register;
2306
2307 VERBOSE_KPRINTF(1, "sceCdGetDiskType Call\n");
2308 cdvd_register = get_cdvd_register(0x0F);
2309 VERBOSE_KPRINTF(1, "sceCdGetDiskType 0x%02x\n", cdvd_register);
2310 return cdvd_register;
2311#else
2312 USE_DEV5_MMIO_HWPORT();
2313
2314 return (u8)dev5_mmio_hwport->m_dev5_reg_00F;
2315#endif
2316}
2317
2318#ifdef CDVD_VARIANT_XOSD
2319static int get_disk_type_ex(void)
2320{
2321 int IntrContext;
2322 int retval;
2323 int state;
2324 USE_DEV5_MMIO_HWPORT();
2325
2326 IntrContext = QueryIntrContext();
2327 if ( IntrContext )
2328 {
2329 CpuSuspendIntr(&state);
2330 }
2331 retval = (g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1) ? 257 : dev5_mmio_hwport->m_dev5_reg_00F;
2332 if ( IntrContext )
2333 {
2334 CpuResumeIntr(state);
2335 }
2336 return retval;
2337}
2338#endif
2339
2340#ifdef CDVD_VARIANT_XOSD
2341int sceCdGetWakeUpReason(void)
2342{
2343 int wakeup_reason_reg;
2344
2345 VERBOSE_KPRINTF(1, "sceCdGetWakeUpReason Call\n");
2346 wakeup_reason_reg = get_cdvd_register(0x15);
2347 if ( wakeup_reason_reg != -1 )
2348 {
2349 wakeup_reason_reg &= 0xF;
2350 }
2351 VERBOSE_KPRINTF(1, "sceCdGetWakeUpReason 0x%02x\n", wakeup_reason_reg);
2352 return wakeup_reason_reg;
2353}
2354#endif
2355
2356int sceCdStatus(void)
2357{
2358 int reg_00A_tmp;
2359#ifndef CDVD_VARIANT_XOSD
2360 u32 status_tmp;
2361#endif
2362#ifndef CDVD_VARIANT_XOSD
2363 USE_DEV5_MMIO_HWPORT();
2364#endif
2365
2366#ifdef CDVD_VARIANT_XOSD
2367 reg_00A_tmp = get_cdvd_register(0x0A);
2368#else
2369 reg_00A_tmp = dev5_mmio_hwport->m_dev5_reg_00A;
2370#endif
2371#ifndef CDVD_VARIANT_XOSD
2372 // The following call to sceCdGetDiskType was inlined
2373 if ( sceCdGetDiskType() == SCECdNODISC )
2374 {
2375 u8 rdata_tmp;
2376
2377 if ( !g_cdvdman_istruct.m_tray_is_open && cdvdman_scmd_sender_03_30(&rdata_tmp, &status_tmp) == 1 && !status_tmp )
2378 {
2379 reg_00A_tmp &= ~SCECdStatShellOpen;
2380 if ( (rdata_tmp & 8) )
2381 {
2382 reg_00A_tmp |= SCECdStatShellOpen;
2383 }
2384 }
2385 if ( (reg_00A_tmp & 0x1E) )
2386 {
2387 reg_00A_tmp = SCECdStatStop;
2388 }
2389 }
2390#endif
2391 if ( g_cdvdman_istruct.m_use_toc )
2392 {
2393 reg_00A_tmp &= ~SCECdStatShellOpen;
2394 }
2395 if ( g_cdvdman_istruct.m_power_flag )
2396 {
2397 return -1;
2398 }
2399 return reg_00A_tmp;
2400}
2401
2402#ifdef CDVD_VARIANT_OSD
2403int sceCdStatus2(void)
2404{
2405 USE_DEV5_MMIO_HWPORT();
2406
2407 return !g_cdvdman_istruct.m_power_flag ? (u8)dev5_mmio_hwport->m_dev5_reg_00A : -1;
2408}
2409#endif
2410
2412{
2413 p->sector = 16 * ((i + 150) % 75 / 10) + (i + 150) % 75 % 10;
2414 p->second = 16 * ((i + 150) / 75 % 60 / 10) + (i + 150) / 75 % 60 % 10;
2415 p->minute = 16 * ((i + 150) / 75 / 60 / 10) + (i + 150) / 75 / 60 % 10;
2416 return p;
2417}
2418
2419// cppcheck-suppress constParameterPointer
2421{
2422 return 75 * (60 * (10 * (p->minute >> 4) + (p->minute & 0xF)) + 10 * (p->second >> 4) + (p->second & 0xF))
2423 + 10 * (p->sector >> 4) + (p->sector & 0xF) - 150;
2424}
2425
2426#ifdef CDVD_VARIANT_DNAS
2427static int read_id_from_rom(int mode, int *buf)
2428{
2429 int chksumint;
2430 unsigned int i;
2431 unsigned int j;
2432 int idinfo[0x20];
2433 int chksumstk;
2434
2435 chksumint = 0;
2436 chksumstk = 0;
2437 for ( i = 0; i < (sizeof(idinfo) / sizeof(idinfo[0])); i += 1 )
2438 {
2439 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2440 {
2441 ((char *)&idinfo)[(i * 4) + j] = ((char *)0xBFBF0000)[(i * 4) + j];
2442 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2443 }
2444 chksumint += chksumstk;
2445 }
2446 for ( ; i < 0x4000; i += 1 )
2447 {
2448 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2449 {
2450 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2451 }
2452 chksumint += chksumstk;
2453 }
2454 if ( chksumint )
2455 {
2456 KPRINTF("# checksum error %d\n", chksumint);
2457 return 0;
2458 }
2459 if ( mode )
2460 {
2461 *buf = idinfo[11];
2462 }
2463 else
2464 {
2465 *buf = idinfo[2];
2466 buf[1] = idinfo[3];
2467 }
2468 return 1;
2469}
2470
2471static int query_boot_mode_6_nonzero(void)
2472{
2473 int *BootMode;
2474
2475 BootMode = QueryBootMode(6);
2476 return !(!BootMode || (*(u16 *)BootMode & 0xFFFC) != 0x60);
2477}
2478
2479static int query_boot_mode_6_zero(void)
2480{
2481 return !QueryBootMode(6);
2482}
2483
2484static int cdvdman_readID(int mode, int *buf)
2485{
2486 u8 id_val[8];
2487 iop_sys_clock_t sysclk;
2488 u32 id_result;
2489
2490 id_result = -1;
2491 if ( query_boot_mode_6_nonzero() )
2492 {
2493 if ( read_id_from_rom(mode, buf) && mode == 1 )
2494 {
2495 if ( *buf == -1 )
2496 {
2497 *buf = 0x1A0002;
2498 }
2499 return 1;
2500 }
2501 return 0;
2502 }
2503 else
2504 {
2505 if ( query_boot_mode_6_zero() )
2506 {
2507 if ( !sceCdRI(id_val, &id_result) || id_result )
2508 {
2509 return 0;
2510 }
2511 }
2512 else
2513 {
2514 if ( !g_readid_systemtime.lo && !g_readid_systemtime.hi )
2515 {
2516 GetSystemTime(&sysclk);
2517 g_readid_systemtime = sysclk;
2518 }
2519 *(iop_sys_clock_t *)id_val = g_readid_systemtime;
2520 }
2521 if ( mode )
2522 {
2523 *buf = *(u32 *)id_val >> 8;
2524 }
2525 else
2526 {
2527 *buf = id_val[0] | 0x8004600;
2528 buf[1] = *(u32 *)&id_val[4];
2529 }
2530 return 1;
2531 }
2532}
2533
2534int sceCdReadGUID(u64 *guid)
2535{
2536 return cdvdman_readID(0, (int *)guid);
2537}
2538
2539int sceCdReadModelID(unsigned int *id)
2540{
2541 return cdvdman_readID(1, (int *)id);
2542}
2543#endif
2544
2545int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
2546{
2547 cdrom_stm_devctl_t devctl_req;
2548 int buf;
2549
2550 // The following Kprintf was added for ioprp300x
2551 VERBOSE_KPRINTF(1, "sceCdStInit call IOP\n");
2552 memset(&devctl_req, 0, sizeof(devctl_req));
2553 devctl_req.m_cmdid = 5;
2554 devctl_req.m_posszarg1 = bufmax;
2555 devctl_req.m_posszarg2 = bankmax;
2556 devctl_req.m_buffer = buffer;
2557 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2558}
2559
2560// cppcheck-suppress constParameterPointer
2561int sceCdStStart(u32 lbn, sceCdRMode *mode)
2562{
2563 cdrom_stm_devctl_t devctl_req;
2564 int buf;
2565
2566 // The following Kprintf was added for ioprp300x
2567 VERBOSE_KPRINTF(1, "sceCdStStart call IOP\n");
2568 memset(&devctl_req, 0, sizeof(devctl_req));
2569 devctl_req.m_rmode.datapattern = mode->datapattern;
2570 devctl_req.m_rmode.spindlctrl = mode->spindlctrl;
2571 devctl_req.m_cmdid = 1;
2572 devctl_req.m_posszarg1 = lbn;
2573 devctl_req.m_rmode.trycount = mode->trycount;
2574 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2575}
2576
2577int sceCdStSeekF(unsigned int lsn)
2578{
2579 cdrom_stm_devctl_t devctl_req;
2580 int buf;
2581
2582 // The following Kprintf was added for ioprp300x
2583 VERBOSE_KPRINTF(1, "sceCdStSeekF call IOP\n");
2584 memset(&devctl_req, 0, sizeof(devctl_req));
2585 devctl_req.m_cmdid = 9;
2586 devctl_req.m_posszarg1 = lsn;
2587 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2588}
2589
2590int sceCdStSeek(u32 lbn)
2591{
2592 cdrom_stm_devctl_t devctl_req;
2593 int buf;
2594
2595 // The following Kprintf was added for ioprp300x
2596 VERBOSE_KPRINTF(1, "sceCdStSeek call IOP\n");
2597 memset(&devctl_req, 0, sizeof(devctl_req));
2598 devctl_req.m_posszarg1 = lbn;
2599 devctl_req.m_cmdid = 4;
2600 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2601}
2602
2603int sceCdStStop(void)
2604{
2605 cdrom_stm_devctl_t devctl_req;
2606 int buf;
2607
2608 // The following Kprintf was added for ioprp300x
2609 VERBOSE_KPRINTF(1, "sceCdStStop call IOP\n");
2610 memset(&devctl_req, 0, sizeof(devctl_req));
2611 devctl_req.m_cmdid = 3;
2612 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2613}
2614
2615int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
2616{
2617 cdrom_stm_devctl_t devctl_req;
2618 int buf;
2619
2620 (void)mode;
2621
2622 // The following Kprintf was added for ioprp300x
2623 VERBOSE_KPRINTF(1, "sceCdStRead call IOP\n");
2624 memset(&devctl_req, 0, sizeof(devctl_req));
2625 devctl_req.m_cmdid = 1;
2626 devctl_req.m_posszarg2 = sectors;
2627 devctl_req.m_buffer = buffer;
2628 if ( devctl("cdrom_stm0:", 0x4394, &devctl_req, sizeof(devctl_req), &buf, 4) < 0 )
2629 {
2630 buf = 0;
2631 }
2632 *error = devctl_req.m_error;
2633 return buf;
2634}
2635
2636int sceCdStPause(void)
2637{
2638 cdrom_stm_devctl_t devctl_req;
2639 int buf;
2640
2641 // The following Kprintf was added for ioprp300x
2642 VERBOSE_KPRINTF(1, "sceCdStPause call IOP\n");
2643 memset(&devctl_req, 0, sizeof(devctl_req));
2644 devctl_req.m_cmdid = 7;
2645 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2646}
2647
2648int sceCdStResume(void)
2649{
2650 cdrom_stm_devctl_t devctl_req;
2651 int buf;
2652
2653 // The following Kprintf was added for ioprp300x
2654 VERBOSE_KPRINTF(1, "sceCdStResume call IOP\n");
2655 memset(&devctl_req, 0, sizeof(devctl_req));
2656 devctl_req.m_cmdid = 8;
2657 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2658}
2659
2660int sceCdStStat(void)
2661{
2662 cdrom_stm_devctl_t devctl_req;
2663 int buf;
2664
2665 // The following Kprintf was added for ioprp300x
2666 VERBOSE_KPRINTF(1, "sceCdStStat call IOP\n");
2667 memset(&devctl_req, 0, sizeof(devctl_req));
2668 devctl_req.m_cmdid = 6;
2669 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2670}
2671
2672static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer)
2673{
2674 int parent_level;
2675 int i;
2676 unsigned int j;
2677 char name_buf[32];
2678
2679 VERBOSE_PRINTF(1, "CdSearchFile: start name= %s layer= %d\n", name, layer);
2680 if ( g_cdvdman_fs_layer != layer )
2681 {
2682 g_cdvdman_fs_cache = 0;
2683 }
2684 if ( !cdvdman_mediactl(0) && g_cdvdman_fs_cache )
2685 {
2686 VERBOSE_KPRINTF(1, "CdSearchFile: cache dir data used\n");
2687 }
2688 else
2689 {
2690 VERBOSE_PRINTF(1, "CdSearchFile Topen= %s\n", name);
2691 if ( !CD_newmedia(layer) )
2692 {
2693 g_cdvdman_fs_cache = 0;
2694 return 0;
2695 }
2696 g_cdvdman_fs_cache = 1;
2697 }
2698 if ( *name != '\\' )
2699 {
2700 return 0;
2701 }
2702 name_buf[0] = 0;
2703 parent_level = 1;
2704 j = 0;
2705 for ( i = 0; i < 8 && name[i]; i += 1 )
2706 {
2707 for ( j = 0; name[i + j] != '\\'; j += 1 )
2708 {
2709 name_buf[j] = name[i + j];
2710 }
2711 name_buf[j] = 0;
2712 parent_level = cdvdman_finddir(parent_level, name_buf);
2713 if ( parent_level == -1 )
2714 {
2715 name_buf[0] = 0;
2716 break;
2717 }
2718 }
2719 if ( i >= 8 )
2720 {
2721 VERBOSE_PRINTF(1, "%s: path level (%d) error\n", name, i);
2722 return 0;
2723 }
2724 if ( !name_buf[0] )
2725 {
2726 VERBOSE_PRINTF(1, "%s: dir was not found\n", name);
2727 return 0;
2728 }
2729 name_buf[j] = 0;
2730 if ( !CD_cachefile(parent_level, layer) )
2731 {
2732 VERBOSE_PRINTF(1, "CdSearchFile: disc error\n");
2733 return 0;
2734 }
2735 VERBOSE_PRINTF(2, "CdSearchFile: searching %s...\n", name_buf);
2736 for ( j = 0;
2737 j < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) && g_cdvdman_filetbl[j].m_file_struct.name[0];
2738 j += 1 )
2739 {
2740 VERBOSE_PRINTF(1, "%d %s %s\n", (int)j, g_cdvdman_filetbl[j].m_file_struct.name, name_buf);
2741 if ( cdvdman_cmpname(g_cdvdman_filetbl[j].m_file_struct.name, name_buf) )
2742 {
2743 VERBOSE_PRINTF(2, "%s:\t found\n", name_buf);
2744 // The following memcpy was inlined
2745 memcpy(fp, &g_cdvdman_filetbl[j], sizeof(cdvdman_filetbl_entry_t));
2746 fp->m_file_struct.lsn += layer ? g_cdvdman_fs_base2 : 0;
2747 return 1;
2748 }
2749 }
2750 VERBOSE_PRINTF(1, "%s: not found\n", name_buf);
2751 return 0;
2752}
2753
2754static int sceCdSearchDir(char *dirname, int layer)
2755{
2756 sceCdlFILE fp;
2757
2758 VERBOSE_PRINTF(1, "_sceCdSearchDir: dir name %s layer %d\n", dirname, layer);
2759 return sceCdLayerSearchFile(&fp, dirname, layer) ? g_cdvdman_fs_cdsec : SCECdErREADCFR;
2760}
2761
2762static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer)
2763{
2764 VERBOSE_PRINTF(1, "_sceCdReadDir: current= %d dsec= %d layer= %d\n", g_cdvdman_fs_cdsec, dsec, layer);
2765 if ( g_cdvdman_fs_cdsec != dsec || g_cdvdman_fs_layer != layer )
2766 {
2767 if ( g_cdvdman_fs_layer != layer )
2768 {
2769 if ( !CD_newmedia(layer) )
2770 {
2771 return -ENOENT;
2772 }
2773 g_cdvdman_fs_cache = 1;
2774 }
2775 if ( !CD_cachefile(dsec, layer) )
2776 {
2777 return -ENOENT;
2778 }
2779 }
2780 if ( g_cdvdman_filetbl[index].m_file_struct.name[0] )
2781 {
2782 VERBOSE_PRINTF(1, "%s:\t found dir_point %d\n", g_cdvdman_filetbl[index].m_file_struct.name, index);
2783 // The following memcpy was inlined
2784 memcpy(fp, &g_cdvdman_filetbl[index], sizeof(cdvdman_filetbl_entry_t));
2785 return 1;
2786 }
2787 return 0;
2788}
2789
2790static int cdvdman_cmpname(const char *p, const char *q)
2791{
2792 return !strncmp(p, q, 12);
2793}
2794
2795static int CD_newmedia(int arg)
2796{
2797 unsigned int DiskType;
2798 unsigned int i;
2799 iso9660_path_t *path_cur;
2800 int state;
2801 int ptsector;
2802
2803 ptsector = 0;
2804#ifdef CDVD_VARIANT_XOSD
2805 DiskType = get_disk_type_ex();
2806#else
2807 DiskType = sceCdGetDiskType();
2808#endif
2809 switch ( DiskType )
2810 {
2811 case SCECdPSCD:
2812 case SCECdPSCDDA:
2813 case SCECdPS2CD:
2814 case SCECdPS2CDDA:
2815 case SCECdPS2DVD:
2816 case SCECdDVDVR:
2817 case SCECdDVDV:
2818 case SCECdIllegalMedia:
2819 break;
2820 default:
2821 VERBOSE_PRINTF(1, "CD_newmedia: Illegal disc media type =%d\n", (int)DiskType);
2822 return 0;
2823 }
2824 g_cdvdman_fs_base2 = 0;
2825 if ( DiskType == SCECdPS2DVD )
2826 {
2827 if ( !DvdDual_infochk() )
2828 {
2829 VERBOSE_PRINTF(1, "CD_newmedia: Get DvdDual_infochk fail\n");
2830 return 0;
2831 }
2832 g_cdvdman_fs_base2 = arg ? g_cdvdman_istruct.m_layer_1_lsn : 0;
2833 }
2834 if ( disc_read(1, g_cdvdman_fs_base2 + 0x10, g_cdvdman_fs_rbuf, arg) != 1 )
2835 {
2836 VERBOSE_PRINTF(1, "CD_newmedia: Read error in disc_read(PVD)\n");
2837 return 0;
2838 }
2839 CpuSuspendIntr(&state);
2840 for ( i = 0; i < g_cdvdman_pathtblsize; i += 1 )
2841 {
2842 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
2843 g_cdvdman_pathtbl[i].m_layer = 0;
2844 g_cdvdman_pathtbl[i].m_nsec = 0;
2845 g_cdvdman_pathtbl[i].m_lsn = 0;
2846 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
2847 }
2848 g_cache_count = 0;
2849 g_cache_table = 0;
2850 g_cache_path_size = 0;
2851 CpuResumeIntr(state);
2852 if ( strncmp((char *)((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_id, "CD001", 5) )
2853 {
2854 VERBOSE_PRINTF(1, "CD_newmedia: Disc format error in cd_read(PVD)\n");
2855 return 0;
2856 }
2857 switch ( DiskType )
2858 {
2859 case SCECdPSCD:
2860 case SCECdPSCDDA:
2861 case SCECdPS2CD:
2862 case SCECdPS2CDDA:
2863 VERBOSE_PRINTF(1, "CD_newmedia: CD Read mode\n");
2864 ptsector = *(u32 *)(((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_type_l_path_table);
2865 break;
2866 case SCECdPS2DVD:
2867 case SCECdDVDVR:
2868 case SCECdDVDV:
2869 VERBOSE_PRINTF(1, "CD_newmedia: DVD Read mode\n");
2870 ptsector = 257;
2871 break;
2872 }
2873 if ( disc_read(1, g_cdvdman_fs_base2 + ptsector, g_cdvdman_fs_rbuf, arg) != 1 )
2874 {
2875 VERBOSE_PRINTF(1, "CD_newmedia: Read error (PT:%08x)\n", ptsector);
2876 return 0;
2877 }
2878 VERBOSE_PRINTF(2, "CD_newmedia: sarching dir..\n");
2879 for ( i = 0, path_cur = (iso9660_path_t *)g_cdvdman_fs_rbuf;
2880 i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0]))
2881 && path_cur < (iso9660_path_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)] && path_cur->m_name_len[0];
2882 i += 1,
2883 path_cur = (iso9660_path_t *)(((char *)path_cur) + path_cur->m_name_len[0] + (path_cur->m_name_len[0] & 1)
2884 + sizeof(iso9660_path_t)) )
2885 {
2886 memcpy(&g_cdvdman_dirtbl[i].m_extent, path_cur->m_extent, sizeof(path_cur->m_extent));
2887 g_cdvdman_dirtbl[i].m_number = i;
2888 memcpy(&g_cdvdman_dirtbl[i].m_parent, path_cur->m_parent, sizeof(path_cur->m_parent));
2889 memcpy(g_cdvdman_dirtbl[i].m_name, path_cur->m_name, path_cur->m_name_len[0]);
2890 g_cdvdman_dirtbl[i].m_name[path_cur->m_name_len[0]] = 0;
2891 VERBOSE_PRINTF(
2892 2,
2893 "\t%08x,%04x,%04x,%s\n",
2894 g_cdvdman_dirtbl[i].m_extent,
2895 g_cdvdman_dirtbl[i].m_number,
2896 g_cdvdman_dirtbl[i].m_parent,
2897 g_cdvdman_dirtbl[i].m_name);
2898 }
2899 if ( i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) )
2900 {
2901 g_cdvdman_dirtbl[i].m_parent = 0;
2902 }
2903 g_cdvdman_fs_cdsec = 0;
2904 g_cdvdman_fs_layer = arg;
2905 VERBOSE_PRINTF(2, "CD_newmedia: %d dir entries found\n", (int)i);
2906 return 1;
2907}
2908
2909static int cdvdman_finddir(int target_parent, const char *target_name)
2910{
2911 unsigned int i;
2912
2913 for ( i = 0; i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) && g_cdvdman_dirtbl[i].m_parent; i += 1 )
2914 {
2915 if ( g_cdvdman_dirtbl[i].m_parent == target_parent && !strcmp(target_name, g_cdvdman_dirtbl[i].m_name) )
2916 {
2917 return i + 1;
2918 }
2919 }
2920 return -1;
2921}
2922
2923static int CD_cachefile(int dsec, int layer)
2924{
2925 iso9660_dirent_t *dirent_cur;
2926 unsigned int i;
2927
2928 if ( dsec == g_cdvdman_fs_cdsec )
2929 {
2930 return 1;
2931 }
2932 if (
2933 disc_read(1, g_cdvdman_dirtbl[dsec - 1].m_extent + (layer ? g_cdvdman_fs_base2 : 0), g_cdvdman_fs_rbuf, layer)
2934 != 1 )
2935 {
2936 VERBOSE_PRINTF(1, "CD_cachefile: dir not found\n");
2937 g_cdvdman_fs_cdsec = 0;
2938 return 0;
2939 }
2940 VERBOSE_PRINTF(2, "CD_cachefile: searching...\n");
2941 for ( i = 0, dirent_cur = (iso9660_dirent_t *)g_cdvdman_fs_rbuf;
2942 i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0]))
2943 && dirent_cur < (iso9660_dirent_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)];
2944 i += 1, dirent_cur = (iso9660_dirent_t *)((char *)dirent_cur + dirent_cur->m_length[0]) )
2945 {
2946 int file_year;
2947
2948 if ( !dirent_cur->m_length[0] )
2949 {
2950 break;
2951 }
2952 memcpy(
2953 &g_cdvdman_filetbl[i].m_file_struct.lsn, dirent_cur->m_extent, sizeof(g_cdvdman_filetbl[i].m_file_struct.lsn));
2954 memcpy(
2955 &g_cdvdman_filetbl[i].m_file_struct.size, dirent_cur->m_size, sizeof(g_cdvdman_filetbl[i].m_file_struct.size));
2956 file_year = dirent_cur->m_date[0] + 1900;
2957 g_cdvdman_filetbl[i].m_file_struct.date[7] = file_year >> 8;
2958 g_cdvdman_filetbl[i].m_file_struct.date[6] = file_year;
2959 g_cdvdman_filetbl[i].m_file_struct.date[5] = dirent_cur->m_date[1];
2960 g_cdvdman_filetbl[i].m_file_struct.date[4] = dirent_cur->m_date[2];
2961 g_cdvdman_filetbl[i].m_file_struct.date[3] = dirent_cur->m_date[3];
2962 g_cdvdman_filetbl[i].m_file_struct.date[2] = dirent_cur->m_date[4];
2963 g_cdvdman_filetbl[i].m_file_struct.date[1] = dirent_cur->m_date[5];
2964 g_cdvdman_filetbl[i].m_flags = dirent_cur->m_flags[0];
2965 switch ( i )
2966 {
2967 case 0:
2968 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, ".");
2969 break;
2970 case 1:
2971 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, "..");
2972 break;
2973 default:
2974 memcpy(g_cdvdman_filetbl[i].m_file_struct.name, dirent_cur->m_name, dirent_cur->m_name_len[0]);
2975 g_cdvdman_filetbl[i].m_file_struct.name[dirent_cur->m_name_len[0]] = 0;
2976 break;
2977 }
2978 VERBOSE_PRINTF(
2979 2,
2980 "\t lsn %d size %d name:%d:%s %d/%d/%d %d:%d:%d\n",
2981 (int)(g_cdvdman_filetbl[i].m_file_struct.lsn),
2982 (int)(g_cdvdman_filetbl[i].m_file_struct.size),
2983 dirent_cur->m_name_len[0],
2984 g_cdvdman_filetbl[i].m_file_struct.name,
2985 file_year,
2986 g_cdvdman_filetbl[i].m_file_struct.date[5],
2987 g_cdvdman_filetbl[i].m_file_struct.date[4],
2988 g_cdvdman_filetbl[i].m_file_struct.date[3],
2989 g_cdvdman_filetbl[i].m_file_struct.date[2],
2990 g_cdvdman_filetbl[i].m_file_struct.date[1]);
2991 }
2992 g_cdvdman_fs_cdsec = dsec;
2993 if ( i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) )
2994 {
2995 g_cdvdman_filetbl[i].m_file_struct.name[0] = 0;
2996 }
2997 VERBOSE_PRINTF(2, "CD_cachefile: %d files found\n", (int)i);
2998 return 1;
2999}
3000
3001static int disc_read(int size, int loc, void *buffer, int layer)
3002{
3003 int f;
3004 int i;
3005 sceCdRMode rmode;
3006 int has_success;
3007
3008 has_success = 1;
3009 f = 0;
3010 rmode.trycount = 16;
3011 VERBOSE_PRINTF(1, "cd_read:lsn= %d size= %d layer= %d\n", loc, size, layer);
3012 if ( cdvdman_l0check(layer) )
3013 {
3014 g_cdvdman_srchspd = 0;
3015 }
3016 switch ( g_cdvdman_srchspd )
3017 {
3018 case SCECdSpinX1:
3019 case SCECdSpinX2:
3020 case SCECdSpinX4:
3021 rmode.spindlctrl = g_cdvdman_srchspd;
3022 break;
3023 case SCECdSpinStm:
3024 case SCECdSpinNom:
3025 rmode.spindlctrl = !!g_cdvdman_srchspd;
3026 break;
3027 default:
3028 rmode.spindlctrl = SCECdSpinNom;
3029 break;
3030 }
3031 rmode.datapattern = SCECdSecS2048;
3032 if ( !g_cdvdman_pathtblflag )
3033 {
3034 has_success = 1;
3035 }
3036 if ( !has_success )
3037 {
3038 int pathcachecnt;
3039
3040 pathcachecnt = (g_cache_count < g_cdvdman_pathtblsize) ? g_cache_count : g_cdvdman_pathtblsize;
3041 for ( i = 0; i < pathcachecnt; i += 1 )
3042 {
3043 VERBOSE_KPRINTF(
3044 1,
3045 "Path table Cache Search lsn:%d:%d nsec:%d:%d layer%d:%d\n",
3046 g_cdvdman_pathtbl[i].m_lsn,
3047 loc,
3048 g_cdvdman_pathtbl[i].m_nsec,
3049 size,
3050 g_cdvdman_pathtbl[i].m_layer,
3051 layer);
3052 if (
3053 g_cdvdman_pathtbl[i].m_lsn == loc && g_cdvdman_pathtbl[i].m_nsec == (unsigned int)size
3054 && g_cdvdman_pathtbl[i].m_layer == layer )
3055 {
3056 break;
3057 }
3058 }
3059 if ( i != pathcachecnt )
3060 {
3061 VERBOSE_KPRINTF(1, "Path table Cache ON:%d\n", g_cdvdman_pathtbl[i].m_cache_path_sz);
3062 if ( lseek(g_cache_path_fd, g_cdvdman_pathtbl[i].m_cache_path_sz, 0) >= 0 )
3063 {
3064 read(g_cache_path_fd, buffer, size << 11);
3065 f = 1;
3066 g_cdvdman_pathtbl[i].m_cache_hit_count += 1;
3067 }
3068 has_success = 1;
3069 }
3070 if ( !has_success )
3071 {
3072 if ( !sceCdRE(loc, size, buffer, &rmode) )
3073 {
3074 return 0;
3075 }
3076 sceCdSync(3);
3077 }
3078 }
3079 if ( !has_success && sceCdGetError() != SCECdErNO )
3080 {
3081 int cache_path_sz;
3082
3083 if ( g_cache_count >= g_cdvdman_pathtblsize )
3084 {
3085 int cachetblo1;
3086 unsigned int cacheblo2;
3087
3088 g_cache_table += 1;
3089 if ( g_cache_table >= g_cdvdman_pathtblsize )
3090 {
3091 g_cache_table = 0;
3092 }
3093 cachetblo1 = g_cache_table;
3094 cacheblo2 = cachetblo1;
3095 for ( i = 0; (unsigned int)i < g_cache_count; i += 1 )
3096 {
3097 if ( cacheblo2 >= g_cdvdman_pathtblsize )
3098 {
3099 cacheblo2 = 0;
3100 }
3101 if (
3102 g_cdvdman_pathtbl[cacheblo2].m_nsec >= (unsigned int)size
3103 && g_cdvdman_pathtbl[cacheblo2].m_cache_hit_count
3104 < (unsigned int)g_cdvdman_pathtbl[cachetblo1].m_cache_hit_count )
3105 {
3106 cachetblo1 = cacheblo2;
3107 }
3108 cacheblo2 += 1;
3109 }
3110 cache_path_sz = g_cdvdman_pathtbl[cachetblo1].m_cache_path_sz;
3111 g_cache_table = cachetblo1;
3112 }
3113 else
3114 {
3115 cache_path_sz = g_cache_path_size;
3116 g_cache_table = g_cache_count;
3117 g_cache_count += 1;
3118 }
3119 if ( lseek(g_cache_path_fd, cache_path_sz, 0) >= 0 )
3120 {
3121 int ptbl_wcache_write_res;
3122
3123 ptbl_wcache_write_res = write(g_cache_path_fd, buffer, size << 11);
3124 if ( ptbl_wcache_write_res == size << 11 )
3125 {
3126 f = 1;
3127 g_cdvdman_pathtbl[g_cache_table].m_cache_path_sz = cache_path_sz;
3128 g_cdvdman_pathtbl[g_cache_table].m_lsn = loc;
3129 g_cdvdman_pathtbl[g_cache_table].m_nsec = size;
3130 g_cdvdman_pathtbl[g_cache_table].m_layer = layer;
3131 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
3132 g_cache_path_size += (g_cache_count < g_cdvdman_pathtblsize) ? ptbl_wcache_write_res : 0;
3133 }
3134 else
3135 {
3136 VERBOSE_KPRINTF(1, "Ptbl_WCache:write %d", ptbl_wcache_write_res);
3137 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
3138 g_cdvdman_pathtbl[g_cache_table].m_layer = 0;
3139 g_cdvdman_pathtbl[g_cache_table].m_nsec = 0;
3140 g_cdvdman_pathtbl[g_cache_table].m_lsn = 0;
3141 }
3142 }
3143 has_success = 1;
3144 }
3145 if ( has_success )
3146 {
3147 if ( f )
3148 {
3149 return size;
3150 }
3151 if ( !sceCdRE(loc, size, buffer, &rmode) )
3152 {
3153 return 0;
3154 }
3155 sceCdSync(3);
3156 if ( sceCdGetError() != SCECdErNO )
3157 {
3158 return size;
3159 }
3160 }
3161 VERBOSE_KPRINTF(1, "cd_read: error code %x\n", sceCdGetError());
3162 return 0;
3163}
3164
3165static int path_tbl_init(u32 blocks, char *fname, int action)
3166{
3167 int num;
3168 int v;
3169 char cachedir[512];
3170 int state;
3171 u32 blocksbs;
3172
3173 num = 0;
3174 v = 0;
3175 if ( action )
3176 {
3177 CpuSuspendIntr(&state);
3178 g_cdvdman_pathtbl = (cdvdman_pathtbl_t *)AllocSysMemory(ALLOC_LAST, sizeof(cdvdman_pathtbl_t) * blocks, 0);
3179 if ( !g_cdvdman_pathtbl )
3180 {
3181 CpuResumeIntr(state);
3182 g_cdvdman_pathtblflag = 0;
3183 return -ENOMEM;
3184 }
3185 CpuResumeIntr(state);
3186 sprintf(cachedir, "%sCache_Path", fname);
3187 v = open(cachedir, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
3188 if ( v >= 0 )
3189 {
3190 u32 i;
3191
3192 g_cache_path_fd = v;
3193 if ( !strncmp(cachedir, "pfs", 3) )
3194 {
3195 blocksbs = blocks << 11;
3196 ioctl2(g_cache_path_fd, PIOCALLOC, &blocksbs, sizeof(blocksbs), 0, 0);
3197 }
3198 for ( i = 0; i < blocks; i += 1 )
3199 {
3200 v = write(g_cache_path_fd, g_cdvdman_fs_rbuf, sizeof(g_cdvdman_fs_rbuf));
3201 if ( v < 0 )
3202 {
3203 break;
3204 }
3205 }
3206 if ( v >= 0 )
3207 {
3208 CpuSuspendIntr(&state);
3209 g_cdvdman_pathtblsize = blocks;
3210 for ( i = 0; i < blocks; i += 1 )
3211 {
3212 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
3213 g_cdvdman_pathtbl[i].m_layer = 0;
3214 g_cdvdman_pathtbl[i].m_nsec = 0;
3215 g_cdvdman_pathtbl[i].m_lsn = 0;
3216 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
3217 }
3218 g_cache_path_size = 0;
3219 g_cache_count = 0;
3220 g_cache_table = 0;
3221 g_cdvdman_pathtblflag = 1;
3222 CpuResumeIntr(state);
3223 return 0;
3224 }
3225 }
3226 }
3227 if ( g_cache_path_fd != -1 )
3228 {
3229 num = close(g_cache_path_fd);
3230 if ( num >= 0 )
3231 {
3232 if ( !strncmp(cachedir, "pfs", 3) )
3233 {
3234 num = remove(cachedir);
3235 }
3236 else if ( !strncmp(cachedir, "host", 4) )
3237 {
3238 num = 0;
3239 remove(cachedir);
3240 }
3241 }
3242 }
3243 CpuSuspendIntr(&state);
3244 g_cache_path_fd = -1;
3245 g_cache_count = 0;
3246 g_cache_table = 0;
3247 g_cache_path_size = 0;
3248 g_cdvdman_pathtblflag = 0;
3249 g_cdvdman_pathtblsize = 0;
3250 FreeSysMemory(g_cdvdman_pathtbl);
3251 g_cdvdman_pathtbl = 0;
3252 CpuResumeIntr(state);
3253 if ( v < 0 )
3254 {
3255 VERBOSE_KPRINTF(1, "path_tbl_init Error %d\n", v);
3256 }
3257 return (!action) ? num : v;
3258}
3259
3260// Unofficial: unused obfuscation code was removed
3261
3262// clang-format off
3263__asm__ (
3264 "\t" ".set push" "\n"
3265 "\t" ".set noat" "\n"
3266 "\t" ".set noreorder" "\n"
3267 "\t" ".global optimized_memcpy" "\n"
3268 "\t" "optimized_memcpy:" "\n"
3269 "\t" " srl $a3, $a2, 2" "\n"
3270 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3271 "\t" " or $a3, $a0, $a1" "\n"
3272 "\t" " andi $a3, $a3, 0x3" "\n"
3273 "\t" " bnez $a3, .Loptimized_memcpy_3" "\n"
3274 "\t" " nop" "\n"
3275 "\t" " srl $a3, $a2, 2" "\n"
3276 "\t" " addiu $at, $zero, 0xC" "\n"
3277 "\t" " div $zero, $a3, $at" "\n"
3278 "\t" " mflo $a3" "\n"
3279 "\t" " mfhi $v1" "\n"
3280 "\t" " beqz $v1, .Loptimized_memcpy_2" "\n"
3281 "\t" " nop" "\n"
3282 "\t" ".Loptimized_memcpy_1:" "\n"
3283 "\t" " lw $v0, 0x0($a1)" "\n"
3284 "\t" " addiu $v1, $v1, -0x1" "\n"
3285 "\t" " sw $v0, 0x0($a0)" "\n"
3286 "\t" " addiu $a1, $a1, 0x4" "\n"
3287 "\t" " bnez $v1, .Loptimized_memcpy_1" "\n"
3288 "\t" " addiu $a0, $a0, 0x4" "\n"
3289 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3290 "\t" " nop" "\n"
3291 "\t" ".Loptimized_memcpy_2:" "\n"
3292 "\t" " lw $v0, 0x0($a1)" "\n"
3293 "\t" " lw $v1, 0x4($a1)" "\n"
3294 "\t" " lw $t0, 0x8($a1)" "\n"
3295 "\t" " lw $t1, 0xC($a1)" "\n"
3296 "\t" " lw $t2, 0x10($a1)" "\n"
3297 "\t" " lw $t3, 0x14($a1)" "\n"
3298 "\t" " lw $t4, 0x18($a1)" "\n"
3299 "\t" " lw $t5, 0x1C($a1)" "\n"
3300 "\t" " lw $t6, 0x20($a1)" "\n"
3301 "\t" " lw $t7, 0x24($a1)" "\n"
3302 "\t" " lw $t8, 0x28($a1)" "\n"
3303 "\t" " lw $t9, 0x2C($a1)" "\n"
3304 "\t" " addiu $a3, $a3, -0x1" "\n"
3305 "\t" " sw $v0, 0x0($a0)" "\n"
3306 "\t" " sw $v1, 0x4($a0)" "\n"
3307 "\t" " sw $t0, 0x8($a0)" "\n"
3308 "\t" " sw $t1, 0xC($a0)" "\n"
3309 "\t" " sw $t2, 0x10($a0)" "\n"
3310 "\t" " sw $t3, 0x14($a0)" "\n"
3311 "\t" " sw $t4, 0x18($a0)" "\n"
3312 "\t" " sw $t5, 0x1C($a0)" "\n"
3313 "\t" " sw $t6, 0x20($a0)" "\n"
3314 "\t" " sw $t7, 0x24($a0)" "\n"
3315 "\t" " sw $t8, 0x28($a0)" "\n"
3316 "\t" " sw $t9, 0x2C($a0)" "\n"
3317 "\t" " addiu $a1, $a1, 0x30" "\n"
3318 "\t" " bnez $a3, .Loptimized_memcpy_2" "\n"
3319 "\t" " addiu $a0, $a0, 0x30" "\n"
3320 "\t" " j .Loptimized_memcpy_12" "\n"
3321 "\t" " nop" "\n"
3322 "\t" ".Loptimized_memcpy_3:" "\n"
3323 "\t" " andi $a3, $a0, 0x3" "\n"
3324 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3325 "\t" " andi $a3, $a1, 0x3" "\n"
3326 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3327 "\t" " nop" "\n"
3328 "\t" " srl $a3, $a2, 2" "\n"
3329 "\t" " addiu $at, $zero, 0xC" "\n"
3330 "\t" " div $zero, $a3, $at" "\n"
3331 "\t" " mflo $a3" "\n"
3332 "\t" " mfhi $v1" "\n"
3333 "\t" " beqz $v1, .Loptimized_memcpy_5" "\n"
3334 "\t" " nop" "\n"
3335 "\t" ".Loptimized_memcpy_4:" "\n"
3336 "\t" " lwl $v0, 0x3($a1)" "\n"
3337 "\t" " lwr $v0, 0x0($a1)" "\n"
3338 "\t" " addiu $v1, $v1, -0x1" "\n"
3339 "\t" " swl $v0, 0x3($a0)" "\n"
3340 "\t" " swr $v0, 0x0($a0)" "\n"
3341 "\t" " addiu $a1, $a1, 0x4" "\n"
3342 "\t" " bnez $v1, .Loptimized_memcpy_4" "\n"
3343 "\t" " addiu $a0, $a0, 0x4" "\n"
3344 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3345 "\t" " nop" "\n"
3346 "\t" ".Loptimized_memcpy_5:" "\n"
3347 "\t" " lwl $v0, 0x3($a1)" "\n"
3348 "\t" " lwr $v0, 0x0($a1)" "\n"
3349 "\t" " lwl $v1, 0x7($a1)" "\n"
3350 "\t" " lwr $v1, 0x4($a1)" "\n"
3351 "\t" " lwl $t0, 0xB($a1)" "\n"
3352 "\t" " lwr $t0, 0x8($a1)" "\n"
3353 "\t" " lwl $t1, 0xF($a1)" "\n"
3354 "\t" " lwr $t1, 0xC($a1)" "\n"
3355 "\t" " lwl $t2, 0x13($a1)" "\n"
3356 "\t" " lwr $t2, 0x10($a1)" "\n"
3357 "\t" " lwl $t3, 0x17($a1)" "\n"
3358 "\t" " lwr $t3, 0x14($a1)" "\n"
3359 "\t" " lwl $t4, 0x1B($a1)" "\n"
3360 "\t" " lwr $t4, 0x18($a1)" "\n"
3361 "\t" " lwl $t5, 0x1F($a1)" "\n"
3362 "\t" " lwr $t5, 0x1C($a1)" "\n"
3363 "\t" " lwl $t6, 0x23($a1)" "\n"
3364 "\t" " lwr $t6, 0x20($a1)" "\n"
3365 "\t" " lwl $t7, 0x27($a1)" "\n"
3366 "\t" " lwr $t7, 0x24($a1)" "\n"
3367 "\t" " lwl $t8, 0x2B($a1)" "\n"
3368 "\t" " lwr $t8, 0x28($a1)" "\n"
3369 "\t" " lwl $t9, 0x2F($a1)" "\n"
3370 "\t" " lwr $t9, 0x2C($a1)" "\n"
3371 "\t" " addiu $a3, $a3, -0x1" "\n"
3372 "\t" " swl $v0, 0x3($a0)" "\n"
3373 "\t" " swr $v0, 0x0($a0)" "\n"
3374 "\t" " swl $v1, 0x7($a0)" "\n"
3375 "\t" " swr $v1, 0x4($a0)" "\n"
3376 "\t" " swl $t0, 0xB($a0)" "\n"
3377 "\t" " swr $t0, 0x8($a0)" "\n"
3378 "\t" " swl $t1, 0xF($a0)" "\n"
3379 "\t" " swr $t1, 0xC($a0)" "\n"
3380 "\t" " swl $t2, 0x13($a0)" "\n"
3381 "\t" " swr $t2, 0x10($a0)" "\n"
3382 "\t" " swl $t3, 0x17($a0)" "\n"
3383 "\t" " swr $t3, 0x14($a0)" "\n"
3384 "\t" " swl $t4, 0x1B($a0)" "\n"
3385 "\t" " swr $t4, 0x18($a0)" "\n"
3386 "\t" " swl $t5, 0x1F($a0)" "\n"
3387 "\t" " swr $t5, 0x1C($a0)" "\n"
3388 "\t" " swl $t6, 0x23($a0)" "\n"
3389 "\t" " swr $t6, 0x20($a0)" "\n"
3390 "\t" " swl $t7, 0x27($a0)" "\n"
3391 "\t" " swr $t7, 0x24($a0)" "\n"
3392 "\t" " swl $t8, 0x2B($a0)" "\n"
3393 "\t" " swr $t8, 0x28($a0)" "\n"
3394 "\t" " swl $t9, 0x2F($a0)" "\n"
3395 "\t" " swr $t9, 0x2C($a0)" "\n"
3396 "\t" " addiu $a1, $a1, 0x30" "\n"
3397 "\t" " bnez $a3, .Loptimized_memcpy_5" "\n"
3398 "\t" " addiu $a0, $a0, 0x30" "\n"
3399 "\t" " j .Loptimized_memcpy_12" "\n"
3400 "\t" " nop" "\n"
3401 "\t" ".Loptimized_memcpy_6:" "\n"
3402 "\t" " andi $a3, $a0, 0x3" "\n"
3403 "\t" " beqz $a3, .Loptimized_memcpy_9" "\n"
3404 "\t" " nop" "\n"
3405 "\t" " srl $a3, $a2, 2" "\n"
3406 "\t" " addiu $at, $zero, 0xC" "\n"
3407 "\t" " div $zero, $a3, $at" "\n"
3408 "\t" " mflo $a3" "\n"
3409 "\t" " mfhi $v1" "\n"
3410 "\t" " beqz $v1, .Loptimized_memcpy_8" "\n"
3411 "\t" " nop" "\n"
3412 "\t" ".Loptimized_memcpy_7:" "\n"
3413 "\t" " lw $v0, 0x0($a1)" "\n"
3414 "\t" " addiu $v1, $v1, -0x1" "\n"
3415 "\t" " swl $v0, 0x3($a0)" "\n"
3416 "\t" " swr $v0, 0x0($a0)" "\n"
3417 "\t" " addiu $a1, $a1, 0x4" "\n"
3418 "\t" " bnez $v1, .Loptimized_memcpy_7" "\n"
3419 "\t" " addiu $a0, $a0, 0x4" "\n"
3420 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3421 "\t" " nop" "\n"
3422 "\t" ".Loptimized_memcpy_8:" "\n"
3423 "\t" " lw $v0, 0x0($a1)" "\n"
3424 "\t" " lw $v1, 0x4($a1)" "\n"
3425 "\t" " lw $t0, 0x8($a1)" "\n"
3426 "\t" " lw $t1, 0xC($a1)" "\n"
3427 "\t" " lw $t2, 0x10($a1)" "\n"
3428 "\t" " lw $t3, 0x14($a1)" "\n"
3429 "\t" " lw $t4, 0x18($a1)" "\n"
3430 "\t" " lw $t5, 0x1C($a1)" "\n"
3431 "\t" " lw $t6, 0x20($a1)" "\n"
3432 "\t" " lw $t7, 0x24($a1)" "\n"
3433 "\t" " lw $t8, 0x28($a1)" "\n"
3434 "\t" " lw $t9, 0x2C($a1)" "\n"
3435 "\t" " addiu $a3, $a3, -0x1" "\n"
3436 "\t" " swl $v0, 0x3($a0)" "\n"
3437 "\t" " swr $v0, 0x0($a0)" "\n"
3438 "\t" " swl $v1, 0x7($a0)" "\n"
3439 "\t" " swr $v1, 0x4($a0)" "\n"
3440 "\t" " swl $t0, 0xB($a0)" "\n"
3441 "\t" " swr $t0, 0x8($a0)" "\n"
3442 "\t" " swl $t1, 0xF($a0)" "\n"
3443 "\t" " swr $t1, 0xC($a0)" "\n"
3444 "\t" " swl $t2, 0x13($a0)" "\n"
3445 "\t" " swr $t2, 0x10($a0)" "\n"
3446 "\t" " swl $t3, 0x17($a0)" "\n"
3447 "\t" " swr $t3, 0x14($a0)" "\n"
3448 "\t" " swl $t4, 0x1B($a0)" "\n"
3449 "\t" " swr $t4, 0x18($a0)" "\n"
3450 "\t" " swl $t5, 0x1F($a0)" "\n"
3451 "\t" " swr $t5, 0x1C($a0)" "\n"
3452 "\t" " swl $t6, 0x23($a0)" "\n"
3453 "\t" " swr $t6, 0x20($a0)" "\n"
3454 "\t" " swl $t7, 0x27($a0)" "\n"
3455 "\t" " swr $t7, 0x24($a0)" "\n"
3456 "\t" " swl $t8, 0x2B($a0)" "\n"
3457 "\t" " swr $t8, 0x28($a0)" "\n"
3458 "\t" " swl $t9, 0x2F($a0)" "\n"
3459 "\t" " swr $t9, 0x2C($a0)" "\n"
3460 "\t" " addiu $a1, $a1, 0x30" "\n"
3461 "\t" " bnez $a3, .Loptimized_memcpy_8" "\n"
3462 "\t" " addiu $a0, $a0, 0x30" "\n"
3463 "\t" " j .Loptimized_memcpy_12" "\n"
3464 "\t" " nop" "\n"
3465 "\t" ".Loptimized_memcpy_9:" "\n"
3466 "\t" " srl $a3, $a2, 2" "\n"
3467 "\t" " addiu $at, $zero, 0xC" "\n"
3468 "\t" " div $zero, $a3, $at" "\n"
3469 "\t" " mflo $a3" "\n"
3470 "\t" " mfhi $v1" "\n"
3471 "\t" " beqz $v1, .Loptimized_memcpy_11" "\n"
3472 "\t" " nop" "\n"
3473 "\t" ".Loptimized_memcpy_10:" "\n"
3474 "\t" " lwl $v0, 0x3($a1)" "\n"
3475 "\t" " lwr $v0, 0x0($a1)" "\n"
3476 "\t" " addiu $v1, $v1, -0x1" "\n"
3477 "\t" " sw $v0, 0x0($a0)" "\n"
3478 "\t" " addiu $a1, $a1, 0x4" "\n"
3479 "\t" " bnez $v1, .Loptimized_memcpy_10" "\n"
3480 "\t" " addiu $a0, $a0, 0x4" "\n"
3481 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3482 "\t" " nop" "\n"
3483 "\t" ".Loptimized_memcpy_11:" "\n"
3484 "\t" " lwl $v0, 0x3($a1)" "\n"
3485 "\t" " lwr $v0, 0x0($a1)" "\n"
3486 "\t" " lwl $v1, 0x7($a1)" "\n"
3487 "\t" " lwr $v1, 0x4($a1)" "\n"
3488 "\t" " lwl $t0, 0xB($a1)" "\n"
3489 "\t" " lwr $t0, 0x8($a1)" "\n"
3490 "\t" " lwl $t1, 0xF($a1)" "\n"
3491 "\t" " lwr $t1, 0xC($a1)" "\n"
3492 "\t" " lwl $t2, 0x13($a1)" "\n"
3493 "\t" " lwr $t2, 0x10($a1)" "\n"
3494 "\t" " lwl $t3, 0x17($a1)" "\n"
3495 "\t" " lwr $t3, 0x14($a1)" "\n"
3496 "\t" " lwl $t4, 0x1B($a1)" "\n"
3497 "\t" " lwr $t4, 0x18($a1)" "\n"
3498 "\t" " lwl $t5, 0x1F($a1)" "\n"
3499 "\t" " lwr $t5, 0x1C($a1)" "\n"
3500 "\t" " lwl $t6, 0x23($a1)" "\n"
3501 "\t" " lwr $t6, 0x20($a1)" "\n"
3502 "\t" " lwl $t7, 0x27($a1)" "\n"
3503 "\t" " lwr $t7, 0x24($a1)" "\n"
3504 "\t" " lwl $t8, 0x2B($a1)" "\n"
3505 "\t" " lwr $t8, 0x28($a1)" "\n"
3506 "\t" " lwl $t9, 0x2F($a1)" "\n"
3507 "\t" " lwr $t9, 0x2C($a1)" "\n"
3508 "\t" " addiu $a3, $a3, -0x1" "\n"
3509 "\t" " sw $v0, 0x0($a0)" "\n"
3510 "\t" " sw $v1, 0x4($a0)" "\n"
3511 "\t" " sw $t0, 0x8($a0)" "\n"
3512 "\t" " sw $t1, 0xC($a0)" "\n"
3513 "\t" " sw $t2, 0x10($a0)" "\n"
3514 "\t" " sw $t3, 0x14($a0)" "\n"
3515 "\t" " sw $t4, 0x18($a0)" "\n"
3516 "\t" " sw $t5, 0x1C($a0)" "\n"
3517 "\t" " sw $t6, 0x20($a0)" "\n"
3518 "\t" " sw $t7, 0x24($a0)" "\n"
3519 "\t" " sw $t8, 0x28($a0)" "\n"
3520 "\t" " sw $t9, 0x2C($a0)" "\n"
3521 "\t" " addiu $a1, $a1, 0x30" "\n"
3522 "\t" " bnez $a3, .Loptimized_memcpy_11" "\n"
3523 "\t" " addiu $a0, $a0, 0x30" "\n"
3524 "\t" ".Loptimized_memcpy_12:" "\n"
3525 "\t" " andi $v1, $a2, 0x3" "\n"
3526 "\t" " beqz $v1, .Loptimized_memcpy_14" "\n"
3527 "\t" " nop" "\n"
3528 "\t" ".Loptimized_memcpy_13:" "\n"
3529 "\t" " lb $v0, 0x0($a1)" "\n"
3530 "\t" " addiu $v1, $v1, -0x1" "\n"
3531 "\t" " sb $v0, 0x0($a0)" "\n"
3532 "\t" " addiu $a1, $a1, 0x1" "\n"
3533 "\t" " bnez $v1, .Loptimized_memcpy_13" "\n"
3534 "\t" " addiu $a0, $a0, 0x1" "\n"
3535 "\t" ".Loptimized_memcpy_14:" "\n"
3536 "\t" " addu $v0, $a2, $zero" "\n"
3537 "\t" " jr $ra" "\n"
3538 "\t" " nop" "\n"
3539 "\t" ".set pop" "\n"
3540);
3541// clang-format on
3542
3543#ifdef DEAD_CODE
3544void hex_dump(u8 *addr_start, int length)
3545{
3546 int i;
3547
3548 KPRINTF("Hex Dump addr %08x\n", addr_start);
3549 for ( i = 0; i < length; i += 1 )
3550 {
3551 if ( !(i & 0xF) && i )
3552 {
3553 PRINTF("\n");
3554 }
3555 KPRINTF(" %02x", addr_start[i]);
3556 }
3557 KPRINTF("\n");
3558}
3559#endif
3560
3561static int cdvdman_initcfg(void)
3562{
3563 int i;
3564 u8 m_version[5];
3565 u32 eflag;
3566
3567 eflag = 0;
3568 for ( i = 0; i <= 100; i += 1 )
3569 {
3570 unsigned int mvored;
3571
3572#ifdef CDVD_VARIANT_XOSD
3573 if ( !sceCdMV(m_version, &eflag) )
3574#else
3575 if ( !sceCdMV(m_version, &eflag) && (eflag & 0x80) )
3576#endif
3577 {
3578 vDelayThread(2000);
3579 VERBOSE_KPRINTF(1, "_sceCdMV error\n");
3580 }
3581 mvored = m_version[3] | (m_version[2] << 8) | (m_version[1] << 16);
3582 g_cdvdman_emudvd9 = m_version[2] & 1;
3583 VERBOSE_KPRINTF(1, "MV %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3584 g_cdvdman_minver_10700 = mvored >= 0x10700;
3585 g_cdvdman_minver_20200 = mvored >= 0x20200;
3586 g_cdvdman_minver_20400 = mvored >= 0x20400;
3587 g_cdvdman_minver_20800 = mvored >= 0x20800;
3588 g_cdvdman_minver_50000 = mvored >= 0x50000;
3589 g_cdvdman_minver_50200 = mvored >= 0x50200;
3590 g_cdvdman_minver_50400 = mvored >= 0x50400;
3591 g_cdvdman_minver_50600 = mvored >= 0x50600;
3592#ifdef CDVD_VARIANT_XOSD
3593 VERBOSE_KPRINTF(0, "M Version %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3594 if ( cdvdman_get_renewal_date(m_version, &eflag) )
3595 {
3596 VERBOSE_KPRINTF(
3597 0,
3598 "M Renewal Date 20%02x/%02x/%02x %02x:%02x\n",
3599 m_version[0],
3600 m_version[1],
3601 m_version[2],
3602 m_version[3],
3603 m_version[4]);
3604 }
3605 g_cdvdman_vernotxxx1x = 0;
3606 if ( g_cdvdman_minver_50600 )
3607 {
3608 // cdvdman_verxxxx1 = (mvored & 0xF) == 1; // not referenced!
3609 KPRINTF("X_model ");
3610 switch ( mvored & 0xF0 )
3611 {
3612 case 0x00:
3613 KPRINTF("量産 OR 量産試作機\n");
3614 break;
3615 case 0x10:
3616 KPRINTF("原理試作機\n");
3617 g_cdvdman_vernotxxx1x = 1;
3618 break;
3619 case 0x20:
3620 KPRINTF("手作り試作機\n");
3621 break;
3622 case 0x30:
3623 KPRINTF("型物試作機\n");
3624 break;
3625 default:
3626 KPRINTF("Unkown\n");
3627 break;
3628 }
3629 }
3630 else
3631 {
3632 KPRINTF("X_model 旧原理試作機 Ver5.6未満 Found\n");
3633 }
3634#endif
3635 g_cdvdman_minver_x_model_15 = (mvored & 0xF) == 1;
3636 g_cdvdman_minver_60000 = mvored >= 0x60000;
3637 g_cdvdman_minver_60200 = mvored >= 0x60200;
3638#ifdef CDVD_VARIANT_OSD
3639 g_cdvdman_minver_60600 = mvored >= 0x60600;
3640#endif
3641 return 1;
3642 }
3643 return 0;
3644}
3645
3646static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *), void *arg)
3647{
3648 return (QueryIntrContext() ? iSetAlarm : SetAlarm)(sys_clock, alarm_cb, arg);
3649}
3650
3651static int vCancelAlarm(unsigned int (*alarm_cb)(void *), void *arg)
3652{
3653 return (QueryIntrContext() ? iCancelAlarm : CancelAlarm)(alarm_cb, arg);
3654}
3655
3656#ifdef DEAD_CODE
3657s32 vSignalSema(s32 sema_id)
3658{
3659 return (QueryIntrContext() ? iSignalSema : SignalSema)(sema_id);
3660}
3661#endif
3662
3663static int vSetEventFlag(int ef, u32 bits)
3664{
3665 return (QueryIntrContext() ? iSetEventFlag : SetEventFlag)(ef, bits);
3666}
3667
3668static int vClearEventFlag(int ef, u32 bits)
3669{
3670 return (QueryIntrContext() ? iClearEventFlag : ClearEventFlag)(ef, bits);
3671}
3672
3673static int vReferEventFlagStatus(int ef, iop_event_info_t *info)
3674{
3675 return (QueryIntrContext() ? iReferEventFlagStatus : ReferEventFlagStatus)(ef, info);
3676}
3677
3678static int vPollEventFlag(int ef, u32 bits, int mode, u32 *efbits)
3679{
3680#ifdef CDVD_VARIANT_XOSD
3681 int retres;
3682 iop_event_info_t efinfo;
3683
3684 if ( !QueryIntrContext() )
3685 {
3686 return PollEventFlag(ef, bits, mode, efbits);
3687 }
3688 retres = iReferEventFlagStatus(ef, &efinfo);
3689 if ( retres )
3690 {
3691 return retres;
3692 }
3693 *efbits = efinfo.currBits;
3694 if ( (mode & 1) ? !(efinfo.currBits & bits) : ((efinfo.currBits & bits) != bits) )
3695 {
3696 return KE_EVF_COND;
3697 }
3698 if ( mode & 0x10 )
3699 {
3700 iClearEventFlag(ef, ~bits);
3701 }
3702 return 0;
3703#else
3704 return PollEventFlag(ef, bits, mode, efbits);
3705#endif
3706}
3707
3708static int vDelayThread(int usec)
3709{
3710 int intrval;
3711 int state;
3712
3713 intrval = CpuSuspendIntr(&state);
3714 CpuResumeIntr(state);
3715 return (!QueryIntrContext() && !intrval) ? DelayThread(usec) : 0;
3716}
3717
3718#ifdef CDVD_VARIANT_XOSD
3719static int get_cdvd_register(int regnr)
3720{
3721 int intrres;
3722 int IntrContext;
3723 int regval;
3724 iop_event_info_t efinfo;
3725 int state;
3726 u32 efbits;
3727
3728 intrres = CpuSuspendIntr(&state);
3729 CpuResumeIntr(state);
3730 IntrContext = QueryIntrContext();
3731 if ( !IntrContext && !intrres )
3732 {
3733 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3734 CpuSuspendIntr(&state);
3735 }
3736 else
3737 {
3738 if ( IntrContext )
3739 {
3740 iReferEventFlagStatus(g_cdvdman_csys_evfid, &efinfo);
3741 }
3742 else
3743 {
3744 ReferEventFlagStatus(g_cdvdman_csys_evfid, &efinfo);
3745 }
3746 if ( !(efinfo.currBits & 1) )
3747 {
3748 return -1;
3749 }
3750 }
3751 if ( update_cd_mode_ps2_atapi() != 1 )
3752 {
3753 regval = ((vu8 *)(0xBF402000))[regnr];
3754 }
3755 else
3756 {
3757 if ( !IntrContext && !intrres )
3758 {
3759 CpuResumeIntr(state);
3760 if ( g_cd_atapi_evfid != -1 )
3761 {
3762 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
3763 }
3764 if ( g_adma_evfid != -1 )
3765 {
3766 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3767 }
3768 if ( g_acmd_evfid != -1 )
3769 {
3770 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3771 }
3772 CpuSuspendIntr(&state);
3773 }
3774 else
3775 {
3776 if ( g_cd_atapi_evfid != -1 )
3777 {
3778 if ( IntrContext )
3779 {
3780 iReferEventFlagStatus(g_cd_atapi_evfid, &efinfo);
3781 }
3782 else
3783 {
3784 ReferEventFlagStatus(g_cd_atapi_evfid, &efinfo);
3785 }
3786 if ( !(efinfo.currBits & 3) )
3787 {
3788 return -1;
3789 }
3790 }
3791 if ( g_adma_evfid != -1 )
3792 {
3793 if ( IntrContext )
3794 {
3795 iReferEventFlagStatus(g_adma_evfid, &efinfo);
3796 }
3797 else
3798 {
3799 ReferEventFlagStatus(g_adma_evfid, &efinfo);
3800 }
3801 if ( !(efinfo.currBits & 1) )
3802 {
3803 return -1;
3804 }
3805 }
3806 if ( g_acmd_evfid != -1 )
3807 {
3808 if ( IntrContext )
3809 {
3810 iReferEventFlagStatus(g_acmd_evfid, &efinfo);
3811 }
3812 else
3813 {
3814 ReferEventFlagStatus(g_acmd_evfid, &efinfo);
3815 }
3816 }
3817 if ( !(efinfo.currBits & 1) )
3818 {
3819 return -1;
3820 }
3821 }
3822 set_cdvd_dev5_base_addr_atapi(2);
3823 regval = ((vu8 *)(0xBF402000))[regnr];
3824 set_cdvd_dev5_base_addr_atapi(1);
3825 if ( !IntrContext && !intrres )
3826 {
3827 if ( g_acmd_evfid != -1 )
3828 {
3829 SetEventFlag(g_acmd_evfid, 1);
3830 }
3831 if ( g_adma_evfid != -1 )
3832 {
3833 SetEventFlag(g_adma_evfid, 1);
3834 }
3835 if ( g_cd_atapi_evfid != -1 )
3836 {
3837 SetEventFlag(g_cd_atapi_evfid, 3);
3838 }
3839 }
3840 }
3841 if ( !IntrContext && !intrres )
3842 {
3843 CpuResumeIntr(state);
3844 SetEventFlag(g_cdvdman_csys_evfid, 1);
3845 }
3846 return regval;
3847}
3848#endif
3849
3850// cppcheck-suppress constParameterCallback
3851static unsigned int read_timeout_alarm_cb(void *userdata)
3852{
3853 int read_timeout;
3854 const iop_sys_clock_t *sys_clock;
3855
3856 sys_clock = (const iop_sys_clock_t *)userdata;
3857 read_timeout = sys_clock->lo / 0x9000;
3858 KPRINTF("Read Time Out %d(msec)\n", read_timeout);
3859 sceCdSC(0xFFFFFFEE, &read_timeout);
3860 return !sceCdBreak();
3861}
3862
3864{
3865 sceCdCBFunc rc;
3866 u32 efbits;
3867
3868 if ( sceCdSync(1) || PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
3869 {
3870 return 0;
3871 }
3872 rc = g_cdvdman_user_cb;
3873 g_cdvdman_user_cb = function;
3874 vSetEventFlag(g_ncmd_evfid, 1);
3875 return rc;
3876}
3877
3878// cppcheck-suppress funcArgNamesDifferent
3879void *sceCdPOffCallback(void (*func)(void *), void *userdata)
3880{
3881 void *old_cb;
3882 int state;
3883
3884 CpuSuspendIntr(&state);
3885 old_cb = g_cdvdman_power_off_callback;
3886 g_cdvdman_power_off_callback = func;
3887 g_cdvdman_power_off_callback_userdata = userdata;
3888 CpuResumeIntr(state);
3889 return old_cb;
3890}
3891
3892#ifdef CDVD_VARIANT_XOSD
3893void *sceCdSetAtapiEjectCallback(int (*func)(int, void *), void *userdata)
3894{
3895 void *old_cb;
3896 int state;
3897
3898 CpuSuspendIntr(&state);
3899 old_cb = g_cdvdman_atapi_eject_bs_power_callback;
3900 g_cdvdman_atapi_eject_bs_power_callback = func;
3901 g_cdvdman_atapi_eject_bs_power_callback_userdata = userdata;
3902 CpuResumeIntr(state);
3903 return old_cb;
3904}
3905#endif
3906
3907int sceCdstm0Cb(void (*p)(int))
3908{
3909 g_cdvdman_cdstm0cb = p;
3910 return 0;
3911}
3912
3913int sceCdstm1Cb(void (*p)(int))
3914{
3915 g_cdvdman_cdstm1cb = p;
3916 return 0;
3917}
3918
3919static int cdvdman_intr_cb(cdvdman_internal_struct_t *s)
3920{
3921 sceCdRMode cdrmode;
3922 int oldstate;
3923 int ext_passthrough;
3924 USE_DEV5_MMIO_HWPORT();
3925
3926 ext_passthrough = 0;
3927 s->m_wait_flag = s->m_waf_set_test;
3928 iSetEventFlag(g_cdvdman_intr_evfid, 0x29);
3929 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
3930 if ( s->m_cdvdman_command == SCECdFuncStandby && s->m_last_error == SCECdErTRMOPN )
3931 {
3932 s->m_last_error = (sceCdStatus() == SCECdErFAIL) ? SCECdErTRMOPN : SCECdErNO;
3933 }
3934 if ( s->m_last_error == SCECdErEOM )
3935 {
3936 s->m_last_error = SCECdErNO;
3937 }
3938 VERBOSE_KPRINTF(
3939 1, "Intr call func_num: %d Err= %02x OnTout= %d\n", g_cdvdman_cmdfunc, (u8)s->m_last_error, s->m_last_read_timeout);
3940 if ( !s->m_scmd_flag )
3941 {
3942 cdvdman_write_scmd(s);
3943 }
3944 if (
3945 (((u8)s->m_last_error == SCECdErREAD && g_cdvdman_cmdfunc == SCECdFuncRead)
3946 || ((u8)s->m_last_error == SCECdErABRT && s->m_last_read_timeout && g_cdvdman_last_cmdfunc == SCECdFuncRead))
3947 && !g_cdvdman_minver_20200 && !s->m_stream_flag && !s->m_dvd_flag && !s->m_recover_status
3948 && s->m_read_mode.trycount != 1 )
3949 {
3950 s->m_sync_error = 0;
3951 s->m_interupt_read_state = 0;
3952 if ( s->m_dec_mode_set )
3953 {
3954 s->m_dec_mode_last_set = 1;
3955 }
3956 else
3957 {
3958 VERBOSE_KPRINTF(1, "dec mode 0x00\n");
3959 s->m_read_chunk_reprocial_32 = 1 + (0x20 / ((!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk));
3960 s->m_dintrlsn = (s->m_read_lsn < 0x61) ? (s->m_read_lsn + s->m_read_sectors + 48) : (s->m_read_lsn - 80);
3961 s->m_read_mode.spindlctrl = 16;
3962 if ( !sceCdRead0_Rty(
3963 s->m_dintrlsn,
3964 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
3965 s->m_read_buf,
3966 &s->m_read_mode,
3967 (u8)s->m_cdvdman_command,
3968 0,
3969 0) )
3970 {
3971 s->m_last_error = SCECdErREAD;
3972 s->m_recover_status = 0;
3973 }
3974 else
3975 {
3976 ext_passthrough = 1;
3977 }
3978 }
3979 }
3980 if ( !ext_passthrough )
3981 {
3982 char dev5_reg_013_masked;
3983
3984 VERBOSE_KPRINTF(1, "Recover_Stat:%d\n", s->m_recover_status);
3985 dev5_reg_013_masked = dev5_mmio_hwport->m_dev5_reg_013 & 0xF;
3986 if ( dev5_reg_013_masked )
3987 {
3988 if (
3989 ((u8)s->m_last_error == SCECdErREAD || ((u8)s->m_last_error == SCECdErABRT && s->m_last_read_timeout))
3990 && !s->m_recover_status && !s->m_stream_flag && g_cdvdman_cmdfunc != 9 && g_cdvdman_cmdfunc != SCECdFuncReadCDDA
3991 && (unsigned int)s->m_read_mode.trycount - 1 >= 4 )
3992 {
3993 s->m_sync_error = 0;
3994 s->m_interupt_read_state = 0;
3995 if ( s->m_dec_mode_set )
3996 {
3997 s->m_dec_mode_last_set = 2;
3998 }
3999 else
4000 {
4001 VERBOSE_KPRINTF(1, "dec mode 0x01\n");
4002 cdrmode.trycount = s->m_read_mode.trycount;
4003 cdrmode.spindlctrl = dev5_reg_013_masked + 13;
4004 cdrmode.datapattern = s->m_read_mode.datapattern;
4005 if ( sceCdRead0_Rty(
4006 s->m_read_lsn,
4007 s->m_read_sectors,
4008 s->m_read_buf,
4009 &cdrmode,
4010 (u8)s->m_cdvdman_command,
4011 s->m_read_chunk,
4012 s->m_read_callback) )
4013 {
4014 s->m_last_error = SCECdErNO;
4015 return 1;
4016 }
4017 s->m_last_error = SCECdErREAD;
4018 }
4019 }
4020 }
4021 s->m_last_read_timeout = 0;
4022 switch ( s->m_recover_status )
4023 {
4024 case 1:
4025 s->m_sync_error = 0;
4026 s->m_interupt_read_state = 0;
4027 if (
4028 s->m_last_error != SCECdErNO
4029 || !sceCdRead0_Rty(
4030 s->m_dintrlsn,
4031 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
4032 s->m_read_buf,
4033 &s->m_read_mode,
4034 (u8)s->m_cdvdman_command,
4035 0,
4036 0) )
4037 {
4038 s->m_last_error = SCECdErREAD;
4039 s->m_recover_status = 0;
4040 }
4041 else
4042 {
4043 ext_passthrough = 1;
4044 }
4045 break;
4046 case 2:
4047 s->m_sync_error = 0;
4048 s->m_interupt_read_state = 0;
4049 if ( sceCdRead0(
4050 s->m_read_lsn, s->m_read_sectors, s->m_read_buf, &s->m_read_mode, s->m_read_chunk, s->m_read_callback) )
4051 {
4052 s->m_last_error = SCECdErNO;
4053 s->m_recover_status = 3;
4054 return 1;
4055 }
4056 s->m_last_error = SCECdErREAD;
4057 s->m_recover_status = 0;
4058 break;
4059 case 3:
4060 s->m_recover_status = 0;
4061 break;
4062 default:
4063 break;
4064 }
4065 }
4066 if ( ext_passthrough )
4067 {
4068 s->m_last_error = SCECdErNO;
4069 s->m_dintrlsn += s->m_read_sectors;
4070 s->m_read_chunk_reprocial_32 -= 1;
4071 s->m_recover_status = (!s->m_read_chunk_reprocial_32) ? 2 : 1;
4072 return 1;
4073 }
4074 if ( s->m_dec_state )
4075 {
4076 sceCdDecSet(0, 0, 0);
4077 }
4078 if ( (s->m_read2_flag == 1 || s->m_read2_flag == 3) && !s->m_use_toc )
4079 {
4080 VERBOSE_KPRINTF(1, "call Read2intrCDVD()\n");
4081 Read2intrCDVD(s->m_read2_flag);
4082 }
4083 s->m_sync_error = 0;
4084 s->m_interupt_read_state = 0;
4085 if ( s->m_dec_state == 2 )
4086 {
4087 s->m_dec_state = 0;
4088 }
4089 if ( s->m_stream_flag == 1 && !s->m_use_toc && !s->m_read2_flag )
4090 {
4091 if ( g_cdvdman_cdstm0cb )
4092 {
4093 g_cdvdman_cdstm0cb(1);
4094 }
4095 else
4096 {
4097 VERBOSE_KPRINTF(1, "Intr func0 no seting");
4098 }
4099 }
4100 if ( !s->m_read2_flag )
4101 {
4102 if ( s->m_stream_flag == 2 && !s->m_use_toc )
4103 {
4104 if ( g_cdvdman_cdstm1cb )
4105 {
4106 g_cdvdman_cdstm1cb(1);
4107 }
4108 else
4109 {
4110 VERBOSE_KPRINTF(1, "Intr func1 no seting");
4111 }
4112 }
4113 else
4114 {
4115 g_cdvdman_readptr = 0;
4116 }
4117 }
4118
4119 VERBOSE_KPRINTF(
4120 1, "Intr call user callback func_addr %08x num %d flg %d\n", g_cdvdman_user_cb, g_cdvdman_cmdfunc, s->m_read2_flag);
4121 if ( g_cdvdman_user_cb && g_cdvdman_cmdfunc && !s->m_read2_flag && !s->m_use_toc )
4122 {
4123 int cmdfunc_tmp;
4124
4125 cmdfunc_tmp = g_cdvdman_cmdfunc;
4126 g_cdvdman_cmdfunc = 0;
4127 if ( cmdfunc_tmp == 14 || cmdfunc_tmp == 9 )
4128 {
4129 cmdfunc_tmp = SCECdFuncRead;
4130 }
4131 g_cdvdman_user_cb(cmdfunc_tmp);
4132 }
4133 if ( !g_cdvdman_user_cb )
4134 {
4135 g_cdvdman_cmdfunc = 0;
4136 }
4137 return 1;
4138}
4139
4140static int intrh_cdrom(void *userdata)
4141{
4142 int conds1;
4143 iop_event_info_t efinfo;
4144#ifdef CDVD_VARIANT_XOSD
4145 int condaddr5;
4146#endif
4147 int intr_cb_res;
4149 USE_DEV5_MMIO_HWPORT();
4150
4151 s = (cdvdman_internal_struct_t *)userdata;
4152 conds1 = 0;
4153#ifdef CDVD_VARIANT_XOSD
4154 if ( s->m_cd_mode_ps2_atapi == 1 )
4155 {
4156 int spd_intr_stat_cur;
4157 int atapi_intr_reason;
4158
4159 VERBOSE_KPRINTF(1, "Atapi Intr Called %d\n", g_cdvdman_debug_atapi_intr++);
4160 condaddr5 = (unsigned int)GetBaseAddress(5) == 0x1F402000;
4161 set_cdvd_dev5_base_addr_atapi(1);
4162 (void)*(vu16 *)0xBF410028; // r_spd_intr_stat
4163 set_cdvd_dev5_base_addr_atapi(2);
4164 atapi_intr_reason = dev5_mmio_hwport->m_dev5_reg_008;
4165 if ( (atapi_intr_reason & 1) )
4166 {
4167 conds1 = 1;
4168 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4169 VERBOSE_KPRINTF(1, "ATAPI DRAGON CMDCMPL Interrupt\n");
4170 }
4171 if ( atapi_intr_reason & 4 )
4172 {
4173 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4174 conds1 = 1;
4175 iSetEventFlag(g_cdvdman_intr_evfid, 4);
4176 iSetEventFlag(g_cdvdman_intr_evfid, 0x10);
4177 set_cdvd_dev5_base_addr_atapi(1);
4178 VERBOSE_KPRINTF(1, "ATAPI POFFRDY Interrupt\n");
4179 if ( g_cdvdman_power_off_callback )
4180 {
4181 g_cdvdman_power_off_callback(g_cdvdman_power_off_callback_userdata);
4182 }
4183 set_cdvd_dev5_base_addr_atapi(2);
4184 }
4185 if ( (atapi_intr_reason & 8) )
4186 {
4187 conds1 = 1;
4188 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4189 if ( !s->m_medium_removal_state )
4190 {
4191 s->m_atapi_disk_ejected = 0;
4192 }
4193 set_cdvd_dev5_base_addr_atapi(1);
4194 VERBOSE_KPRINTF(1, "ATAPI EJECT Interrupt\n");
4195 if ( s->m_cd_atapi_intr_callback && !s->m_medium_removal_state )
4196 {
4197 VERBOSE_KPRINTF(1, "EJECT Stop Call\n");
4198 s->m_cd_atapi_intr_callback(1);
4199 }
4200 iSetEventFlag(g_cdvdman_intr_evfid, 0x40);
4201 if ( g_cdvdman_atapi_eject_bs_power_callback )
4202 {
4203 VERBOSE_KPRINTF(1, "ATAPI EJECT Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4204 g_cdvdman_atapi_eject_bs_power_callback(1, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4205 }
4206 set_cdvd_dev5_base_addr_atapi(2);
4207 }
4208 if ( (atapi_intr_reason & 0x10) )
4209 {
4210 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4211 conds1 = 1;
4212 set_cdvd_dev5_base_addr_atapi(1);
4213 VERBOSE_KPRINTF(1, "ATAPI BS_Power DET Interrupt\n");
4214 iSetEventFlag(g_cdvdman_intr_evfid, 0x80);
4215 if ( g_cdvdman_atapi_eject_bs_power_callback )
4216 {
4217 VERBOSE_KPRINTF(1, "ATAPI BS_Power Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4218 g_cdvdman_atapi_eject_bs_power_callback(2, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4219 }
4220 }
4221 set_cdvd_dev5_base_addr_atapi(1);
4222 if ( g_cdvdman_vernotxxx1x && conds1 )
4223 {
4224 *(vu16 *)0xBF41002A &= ~0x100; // r_spd_intr_mask
4225 *(vu16 *)0xBF41002A |= 0x100; // r_spd_intr_mask
4226 (void)*(vu16 *)0xBF41002A; // r_spd_intr_mask
4227 }
4228 spd_intr_stat_cur = *(vu16 *)0xBF410028; // r_spd_intr_stat
4229 VERBOSE_KPRINTF(
4230 1,
4231 "Atapi Intr Mode:%d addr:%08x Reason:%02x SPD_INTR_STAT %x\n",
4232 s->m_cd_mode_ps2_atapi,
4233 s->m_cd_atapi_intr_callback,
4234 atapi_intr_reason,
4235 spd_intr_stat_cur);
4236 if ( (spd_intr_stat_cur & 3) && (*g_cdvdreg_bf80146c & 4) )
4237 {
4238 if ( s->m_cd_atapi_intr_callback )
4239 {
4240 s->m_cd_atapi_intr_callback(0);
4241 VERBOSE_KPRINTF(1, "Atapi Intr called\n");
4242 }
4243 if ( !s->m_scmd_flag )
4244 {
4245 VERBOSE_KPRINTF(1, "Intr call set_prev_command.\n");
4246 set_cdvd_dev5_base_addr_atapi(2);
4247 cdvdman_write_scmd(s);
4248 set_cdvd_dev5_base_addr_atapi(1);
4249 }
4250 }
4251 else if ( !conds1 )
4252 {
4253 if ( (*g_cdvdreg_bf80146c & 4) )
4254 {
4255 VERBOSE_KPRINTF(1, "No_Reason Intr\n");
4256 }
4257 else
4258 {
4259 VERBOSE_KPRINTF(1, "already 9611 Power Off Intr\n");
4260 }
4261 }
4262 if ( condaddr5 )
4263 {
4264 set_cdvd_dev5_base_addr_atapi(2);
4265 VERBOSE_KPRINTF(1, "Cur PS2 IO Intr Called\n");
4266 }
4267 return 1;
4268 }
4269 VERBOSE_KPRINTF(1, "Dragon Intr Called\n");
4270 condaddr5 = (unsigned int)GetBaseAddress(5) == 0xBF410000;
4271 if ( condaddr5 )
4272 {
4273 set_cdvd_dev5_base_addr_atapi(2);
4274 }
4275#endif
4276 s->m_waf_set_test = s->m_wait_flag;
4277 if ( (u8)s->m_last_error != SCECdErABRT )
4278 {
4279 s->m_last_error = dev5_mmio_hwport->m_dev5_reg_006;
4280 }
4281 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4282 {
4283 s->m_waf_set_test = (!(dev5_mmio_hwport->m_dev5_reg_005 & 1)) ? 1 : -1;
4284 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4285 conds1 = 1;
4286 }
4287 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4288 {
4289 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4290 iSetEventFlag(g_cdvdman_intr_evfid, 4);
4291 iSetEventFlag(g_cdvdman_intr_evfid, 0x10);
4292 // The following Kprintf was added for ioprp300x
4293 VERBOSE_KPRINTF(1, "PS2 POWER OFF Interrupt\n");
4294 if ( g_cdvdman_power_off_callback )
4295 {
4296 g_cdvdman_power_off_callback(g_cdvdman_power_off_callback_userdata);
4297 }
4298 if ( !conds1 )
4299 {
4300 return 1;
4301 }
4302 }
4303 else
4304 {
4305 s->m_waf_set_test = 1;
4306 s->m_ncmd_intr_count += 1;
4307 dev5_mmio_hwport->m_dev5_reg_008 = 2;
4308 }
4309#ifdef CDVD_VARIANT_XOSD
4310 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 8) )
4311 {
4312 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4313 VERBOSE_KPRINTF(1, "PS2 EJECT Interrupt\n");
4314 iSetEventFlag(g_cdvdman_intr_evfid, 0x40);
4315 if ( !s->m_medium_removal_state )
4316 {
4317 s->m_atapi_disk_ejected = 0;
4318 }
4319 if ( g_cdvdman_atapi_eject_bs_power_callback )
4320 {
4321 VERBOSE_KPRINTF(1, "PS2 EJECT Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4322 g_cdvdman_atapi_eject_bs_power_callback(1, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4323 }
4324 }
4325 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 0x10) )
4326 {
4327 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4328 VERBOSE_KPRINTF(1, "PS2 BS_Power DET Interrupt\n");
4329 iSetEventFlag(g_cdvdman_intr_evfid, 0x80);
4330 if ( g_cdvdman_atapi_eject_bs_power_callback )
4331 {
4332 VERBOSE_KPRINTF(1, "PS2 BS_Power Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4333 g_cdvdman_atapi_eject_bs_power_callback(2, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4334 }
4335 }
4336#endif
4337 iReferEventFlagStatus(g_cdvdman_intr_evfid, &efinfo);
4338 if ( !(efinfo.currBits & 0x20) )
4339 {
4340 // The following Kprintf was added for ioprp300x
4341 VERBOSE_KPRINTF(1, "Now DMA Working evfid:%08x\n", efinfo.currBits);
4342 if ( s->m_last_error == SCECdErNO )
4343 {
4344 s->m_drive_interupt_request = 1;
4345#ifdef CDVD_VARIANT_XOSD
4346 if ( condaddr5 )
4347 {
4348 set_cdvd_dev5_base_addr_atapi(1);
4349 }
4350#endif
4351 return 1;
4352 }
4353 if ( s->m_last_error == SCECdErEOM )
4354 {
4355 intrh_dma_3(s);
4356 }
4357 }
4358 intr_cb_res = cdvdman_intr_cb(s);
4359#ifdef CDVD_VARIANT_XOSD
4360 if ( condaddr5 )
4361 {
4362 set_cdvd_dev5_base_addr_atapi(1);
4363 }
4364#endif
4365 return intr_cb_res;
4366}
4367
4368static u32 cdvdman_l1start(const u8 *toc)
4369{
4370 return toc[23] + (toc[22] << 8) + (toc[21] << 16) - 0x30000 + 1;
4371}
4372
4373static int DvdDual_infochk(void)
4374{
4375#ifdef CDVD_VARIANT_OSD
4376 // From DVD Player 3.11
4377 if ( QueryIntrContext() || !(cdvdman_mediactl(3) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
4378#else
4379 if ( QueryIntrContext() || !(cdvdman_mediactl(4) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
4380#endif
4381 {
4382 return 1;
4383 }
4384 g_cdvdman_istruct.m_use_toc = 1;
4385 if ( !cdvdman_gettoc(g_cdvdman_ptoc) )
4386 {
4387 g_cdvdman_istruct.m_use_toc = 0;
4388 g_cdvdman_istruct.m_opo_or_para = -1;
4389 return 0;
4390 }
4391 g_cdvdman_istruct.m_use_toc = 0;
4392 g_cdvdman_istruct.m_layer_1_lsn = cdvdman_l1start(g_cdvdman_ptoc);
4393 g_cdvdman_istruct.m_opo_or_para = ((g_cdvdman_ptoc[14] & 0x60)) ? (((g_cdvdman_ptoc[14] & 0x10)) ? 2 : 1) : 0;
4394 if ( g_cdvdman_istruct.m_dual_layer_emulation )
4395 {
4396 VERBOSE_KPRINTF(1, "CDVD:DualEmuON\n");
4397 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
4398 g_cdvdman_istruct.m_opo_or_para = 0;
4399 }
4400 VERBOSE_KPRINTF(
4401 1,
4402 "DvdDual_info: %02x\tLayer1_LSN:%d opo_or_para %d\n",
4403 g_cdvdman_ptoc[14],
4404 g_cdvdman_istruct.m_layer_1_lsn,
4405 (u8)g_cdvdman_istruct.m_opo_or_para);
4406 return 1;
4407}
4408
4409static u32 sceCdLsnDualChg(u32 lsn)
4410{
4411 int layer_disk_needed;
4412 u32 change_lsn;
4413 sceCdRMode cdrmode;
4414 int has_change_lsn;
4415
4416 layer_disk_needed = 2;
4417 has_change_lsn = 0;
4418 if ( cdvdman_isdvd() && DvdDual_infochk() )
4419 {
4420 if ( g_cdvdman_istruct.m_dual_layer_emulation )
4421 {
4422 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
4423 {
4424 layer_disk_needed = 1;
4425 }
4426 if ( g_cdvdman_istruct.m_current_dvd && lsn < g_cdvdman_istruct.m_current_dvd_lsn )
4427 {
4428 layer_disk_needed = 0;
4429 }
4430 if ( layer_disk_needed == 2 )
4431 {
4432 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
4433 has_change_lsn = 1;
4434 }
4435 else if ( !QueryIntrContext() )
4436 {
4437 u32 traychk;
4438
4439 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
4440 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4441 {
4442 ;
4443 }
4444 cdrmode.trycount = 0;
4445 cdrmode.spindlctrl = SCECdSpinStm;
4446 cdrmode.datapattern = SCECdSecS2048;
4447 g_cdvdman_istruct.m_use_toc = 1;
4448 while ( layer_disk_needed != 2 )
4449 {
4450 if ( cdvdman_isdvd() )
4451 {
4452 int read0_result;
4453
4454 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
4455 sceCdSync(3);
4456 if ( g_cdvdman_istruct.m_last_error == SCECdErNO || read0_result )
4457 {
4458 int i;
4459
4460 for ( i = 0; i < 20; i += 1 )
4461 {
4462 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
4463 {
4464 break;
4465 }
4466 }
4467 if ( i == 20 && g_cdvdman_ptoc[131] == 2 && (g_cdvdman_ptoc[132] & 2) )
4468 {
4469 if ( layer_disk_needed == g_cdvdman_ptoc[133] )
4470 {
4471 g_cdvdman_istruct.m_current_dvd = layer_disk_needed;
4472 layer_disk_needed = 2;
4473 }
4474 else
4475 {
4476 VERBOSE_KPRINTF(0, "CDVD: Layer_%d Disk not Found\n", layer_disk_needed);
4477 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
4478 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
4479 {
4480 layer_disk_needed = 1;
4481 }
4482 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4483 {
4484 ;
4485 }
4486 }
4487 }
4488 else
4489 {
4490 VERBOSE_KPRINTF(0, "CDVD: Not Master Disk %s\n", (const char *)&g_cdvdman_ptoc[i + 104]);
4491 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4492 {
4493 ;
4494 }
4495 }
4496 }
4497 else
4498 {
4499 VERBOSE_KPRINTF(1, "CDVD: LsnDualChg Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
4500 }
4501 }
4502 else
4503 {
4504 vDelayThread(16000);
4505 }
4506 }
4507 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
4508 g_cdvdman_istruct.m_use_toc = 0;
4509 has_change_lsn = 1;
4510 }
4511 }
4512 else
4513 {
4514 change_lsn =
4515 lsn - ((g_cdvdman_istruct.m_opo_or_para && (lsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn)) ? 0x10 : 0);
4516 has_change_lsn = 1;
4517 }
4518 }
4519 if ( has_change_lsn )
4520 {
4521 VERBOSE_KPRINTF(1, "CDVD: sceCdLsnDualChg lsn %d: change lsn %d\n", lsn, change_lsn);
4522 }
4523 return has_change_lsn ? change_lsn : lsn;
4524}
4525
4526int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
4527{
4528 int read0_result;
4529 int i;
4530 sceCdRMode cdrmode;
4531
4532 *on_dual = 0;
4533 *layer1_start = 0;
4534 g_cdvdman_istruct.m_dual_layer_emulation = 0;
4535#ifndef CDVD_VARIANT_XOSD
4536 if ( !cdvdman_isdvd() )
4537 {
4538 return 1;
4539 }
4540#endif
4541 if ( !g_cdvdman_emudvd9 )
4542 {
4543 if ( !DvdDual_infochk() )
4544 {
4545 return 0;
4546 }
4547 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
4548 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4549 return 1;
4550 }
4551#ifdef CDVD_VARIANT_OSD
4552 if ( !cdvdman_isdvd() )
4553 {
4554 return 1;
4555 }
4556#endif
4557#ifndef CDVD_VARIANT_XOSD
4558 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
4559 {
4560 return 0;
4561 }
4562#endif
4563 cdrmode.trycount = 0;
4564 cdrmode.spindlctrl = SCECdSpinStm;
4565 cdrmode.datapattern = SCECdSecS2048;
4566 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
4567 sceCdSync(3);
4568 if ( g_cdvdman_istruct.m_last_error != SCECdErNO && !read0_result )
4569 {
4570 VERBOSE_KPRINTF(1, "CDVD: ReadDvdDualInfo Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
4571 return 0;
4572 }
4573 for ( i = 0; i < 20; i += 1 )
4574 {
4575 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
4576 {
4577 break;
4578 }
4579 }
4580 if ( i != 20 )
4581 {
4582 if ( !DvdDual_infochk() )
4583 {
4584 return 0;
4585 }
4586 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
4587 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4588 return 1;
4589 }
4590 if ( g_cdvdman_ptoc[131] != 2 || !(g_cdvdman_ptoc[132] & 2) )
4591 {
4592 return 1;
4593 }
4594 g_cdvdman_istruct.m_current_dvd = g_cdvdman_ptoc[133];
4595 g_cdvdman_istruct.m_current_dvd_lsn =
4596 g_cdvdman_ptoc[134] + (g_cdvdman_ptoc[135] << 8) + (g_cdvdman_ptoc[136] << 16) + (g_cdvdman_ptoc[137] << 24) + 1;
4597 g_cdvdman_istruct.m_opo_or_para = 0;
4598 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
4599 g_cdvdman_istruct.m_dual_layer_emulation = 1;
4600 *on_dual = 1;
4601 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4602 VERBOSE_KPRINTF(
4603 1,
4604 "sceCdReadDvdDualInfo():Cur_Disk %d layer1_start %d\n",
4605 (u8)g_cdvdman_istruct.m_current_dvd,
4606 g_cdvdman_istruct.m_current_dvd_lsn);
4607 return 1;
4608}
4609
4610int sceCdSC(int code, int *param)
4611{
4612 void *poffarg_tmp;
4613 int *BootMode;
4614 int state;
4615 u32 efbits;
4616#ifdef CDVD_VARIANT_XOSD
4617 u8 regval;
4618#endif
4619
4620 switch ( code )
4621 {
4622#ifdef CDVD_VARIANT_XOSD
4623 case 0xFFFFFFD6:
4624 CpuSuspendIntr(&state);
4625 set_cdvd_dev5_base_addr_atapi(2);
4626 regval = ((vu8 *)(0xBF402000))[*param];
4627 set_cdvd_dev5_base_addr_atapi(1);
4628 CpuResumeIntr(state);
4629 return regval;
4630 case 0xFFFFFFD7:
4631 CpuSuspendIntr(&state);
4632 *param = (int)&g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open;
4633 CpuResumeIntr(state);
4634 return 1;
4635 case 0xFFFFFFD8:
4636 return sc_ffffffd8((u32 *)param);
4637 case 0xFFFFFFD9:
4638 CpuSuspendIntr(&state);
4639 *param = (int)&g_cdvdman_istruct.m_atapi_disk_ejected;
4640 CpuResumeIntr(state);
4641 return 1;
4642 case 0xFFFFFFDA:
4643 return get_disk_type_ex();
4644 case 0xFFFFFFDB:
4645 CpuSuspendIntr(&state);
4646 *(&g_cdvdman_istruct.m_var_sc_ffffffdb) = (int)param;
4647 CpuResumeIntr(state);
4648 return 1;
4649 case 0xFFFFFFDC:
4650 return g_cdvdman_vernotxxx1x;
4651 case 0xFFFFFFDD:
4652 return get_cdvd_register(*param);
4653 case 0xFFFFFFDF:
4654 g_adma_evfid = *param;
4655 return 1;
4656 case 0xFFFFFFE0:
4657 g_acmd_evfid = *param;
4658 return 1;
4659 case 0xFFFFFFE1:
4660 CpuSuspendIntr(&state);
4661 g_cdvdman_istruct.m_chgsys_callback = (void *)(int)param;
4662 CpuResumeIntr(state);
4663 return 1;
4664 case 0xFFFFFFE4:
4665 g_cd_atapi_evfid = *param;
4666 return 1;
4667 case 0xFFFFFFE5:
4668 CpuSuspendIntr(&state);
4669 g_cdvdman_istruct.m_cd_atapi_intr_callback = (void *)(int)param;
4670 CpuResumeIntr(state);
4671 return 1;
4672#endif
4673 case 0xFFFFFFE6:
4674 CpuSuspendIntr(&state);
4675 *param = (int)g_cdvdman_power_off_callback;
4676 poffarg_tmp = g_cdvdman_power_off_callback_userdata;
4677 CpuResumeIntr(state);
4678 return (int)poffarg_tmp;
4679 case 0xFFFFFFE7:
4680 return g_scmd_evfid;
4681 case 0xFFFFFFE9:
4682 return sceCdLsnDualChg(*param);
4683 case 0xFFFFFFEA:
4684 return DvdDual_infochk();
4685 case 0xFFFFFFEE:
4686 g_cdvdman_istruct.m_last_read_timeout = *param;
4687 return 0;
4688 case 0xFFFFFFEF:
4689 return g_cdvdman_stream_timeout;
4690 case 0xFFFFFFF0:
4691 *param = (int)&g_verbose_level;
4692 return 0xFF;
4693 case 0xFFFFFFF1:
4694 return g_cdvdman_sync_timeout;
4695 case 0xFFFFFFF2:
4696 *param = (int)&g_cdvdman_istruct;
4697 return 0xFF;
4698 case 0xFFFFFFF3:
4699 BootMode = QueryBootMode(4);
4700 switch ( BootMode ? *(u8 *)BootMode : 0xFF )
4701 {
4702 case 0:
4703 case 1:
4704 case 2:
4705 g_cdvdman_mmode = 0xFF;
4706 break;
4707 case 3:
4708 g_cdvdman_mmode = SCECdMmodeCd;
4709 break;
4710 default:
4711 break;
4712 }
4713 return 1;
4714 case 0xFFFFFFF4:
4715#ifdef CDVD_VARIANT_OSD
4716 return 1;
4717#else
4718 // The following call to sceCdGetDiskType was inlined
4719 switch ( sceCdGetDiskType() )
4720 {
4721 case SCECdPSCD:
4722 case SCECdPSCDDA:
4723 case SCECdPS2CD:
4724 case SCECdPS2CDDA:
4725 return g_cdvdman_mmode == SCECdMmodeCd || g_cdvdman_mmode == 0xFF;
4726 case SCECdPS2DVD:
4727 return g_cdvdman_mmode == SCECdMmodeDvd || g_cdvdman_mmode == 0xFF;
4728 case SCECdCDDA:
4729 return g_cdvdman_mmode == 0xFF;
4730 default:
4731 return 0;
4732 }
4733#endif
4734 case 0xFFFFFFF5:
4735 return g_cdvdman_intr_evfid;
4736 case 0xFFFFFFF6:
4737 if ( *param )
4738 {
4739 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
4740 }
4741 else
4742 {
4743 SetEventFlag(g_fio_fsv_evfid, 1);
4744 }
4745 g_cdvdman_ee_rpc_fno = *param;
4746 VERBOSE_KPRINTF(1, "EE_ncmd_working code= %d\n", *param);
4747 return g_cdvdman_ee_rpc_fno;
4748 case 0xFFFFFFF7:
4749 return (u16)_irx_id.v;
4750 case 0xFFFFFFF8:
4751 g_cdvdman_spinctl = *param;
4752 return 1;
4753 case 0xFFFFFFFC:
4754 return g_cdvdman_cd36key;
4755 case 0xFFFFFFFD:
4756 return g_cdvdman_istruct.m_read2_flag;
4757 case 0xFFFFFFFE:
4758 g_cdvdman_istruct.m_last_error = *(u8 *)param;
4759 return (u8)g_cdvdman_istruct.m_last_error;
4760 case 0xFFFFFFFF:
4761 case 0:
4762 case 1:
4763 case 2:
4764 *param = (u8)g_cdvdman_istruct.m_last_error;
4765 if ( code != -1 )
4766 {
4767 g_cdvdman_istruct.m_stream_flag = code;
4768 }
4769 return g_cdvdman_istruct.m_stream_flag;
4770 default:
4771 VERBOSE_KPRINTF(1, "sceCdSC func_num Not found %d\n", code);
4772 return 0;
4773 }
4774}
4775
4776static void cdvdman_init(void)
4777{
4778 int *BootMode;
4779 unsigned int i;
4780 int scres_unused;
4781 u32 argres;
4782#ifdef CDVD_VARIANT_XOSD
4783 int chgsys_tmp;
4784#endif
4785 USE_DEV5_MMIO_HWPORT();
4786
4787#ifdef CDVD_VARIANT_XOSD
4788 {
4789 int state;
4790 CpuSuspendIntr(&state);
4791 g_cdvdman_istruct.m_cd_mode_ps2_atapi = 2;
4792 cdvdman_change_drive(2);
4793 CpuResumeIntr(state);
4794 }
4795#endif
4796 g_cdvdman_user_cb = 0;
4797 g_cdvdman_power_off_callback = 0;
4798 g_cdvdman_cmdfunc = 0;
4799 g_cdvdman_istruct.m_drive_interupt_request = 0;
4800 RegisterIntrHandler(IOP_IRQ_CDVD, 1, intrh_cdrom, &g_cdvdman_istruct);
4801 RegisterIntrHandler(IOP_IRQ_DMA_CDVD, 1, intrh_dma_3, &g_cdvdman_istruct);
4802 EnableIntr(IOP_IRQ_CDVD);
4803 sceCdSC(0xFFFFFFF3, &scres_unused);
4804 dmac_set_dpcr(dmac_get_dpcr() | 0x8000);
4805 dmac_ch_set_chcr(3, 0);
4806#ifdef CDVD_VARIANT_XOSD
4807 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 0x10) )
4808 {
4809 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4810 }
4811 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 8) )
4812 {
4813 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4814 }
4815#endif
4816 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4817 {
4818 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4819 }
4820 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4821 {
4822 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4823 }
4824#ifndef CDVD_VARIANT_XOSD
4825 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4826#endif
4827 g_cdvdman_istruct.m_tray_is_open = !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen);
4828#ifdef CDVD_VARIANT_XOSD
4829 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4830#endif
4831 cdvdman_initcfg();
4832 BootMode = QueryBootMode(6);
4833 g_cdvdman_istruct.m_no_dec_flag = BootMode ? ((*(u16 *)BootMode & 0xFFFC) == 0x60) : 0;
4834 for ( i = 0; i <= 60 && (!sceCdCancelPOffRdy(&argres) || argres); i += 1 )
4835 {
4836 DelayThread(16000);
4837 }
4838#ifdef CDVD_VARIANT_XOSD
4839 {
4840 u32 medium_res;
4841 int MediumRemoval;
4842
4843 for ( i = 0; i <= 60 && (!sceCdSetMediumRemoval(0, &argres) || argres); i += 1 )
4844 {
4845 DelayThread(16000);
4846 }
4847 for ( i = 0; i <= 60 && (!(MediumRemoval = sceCdGetMediumRemoval(&medium_res, &argres)) || argres); i += 1 )
4848 {
4849 DelayThread(16000);
4850 }
4851 g_cdvdman_istruct.m_medium_removal_state = (MediumRemoval && !argres) ? medium_res : 0;
4852 {
4853 int state;
4854
4855 CpuSuspendIntr(&state);
4856 chgsys_tmp = (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen);
4857 g_cdvdman_istruct.m_cd_mode_ps2_atapi =
4858 (chgsys_tmp || (!(dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && dev5_mmio_hwport->m_dev5_reg_00F != 6)) ? 2 : 1;
4859 cdvdman_change_drive(g_cdvdman_istruct.m_cd_mode_ps2_atapi);
4860 CpuResumeIntr(state);
4861 }
4862 if ( chgsys_tmp )
4863 {
4864 sceCdChgSys(1);
4865 }
4866 }
4867#endif
4868}
4869
4870int sceCdInit(int mode)
4871{
4872 VERBOSE_PRINTF(1, "sceCdInit called mode= %d\n", mode);
4873 if ( mode == SCECdEXIT )
4874 {
4875 int oldstate;
4876
4877 g_cdvdman_istruct.m_cd_inited = 0;
4878#ifndef CDVD_VARIANT_XOSD
4879 sceCdBreak();
4880 sceCdSync(3);
4881 cdvdman_ncmd_sender_06();
4882#endif
4883 sceCdSync(0);
4884 VERBOSE_PRINTF(1, "Cdvdman Exit\n");
4885 DisableIntr(IOP_IRQ_CDVD, &oldstate);
4886 ReleaseIntrHandler(IOP_IRQ_CDVD);
4887 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
4888 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
4889 }
4890 else
4891 {
4892 VERBOSE_PRINTF(1, "Cdvdman Init\n");
4893 g_cdvdman_istruct.m_read2_flag = 0;
4894 g_cdvdman_istruct.m_dec_shift = 0;
4895 g_cdvdman_istruct.m_check_version = 0;
4896 g_cdvdman_istruct.m_dec_state = 0;
4897#ifdef CDVD_VARIANT_XOSD
4898 if ( update_cd_mode_ps2_atapi() != 1 )
4899#endif
4900 {
4901 sceCdDecSet(0, 0, 0);
4902 }
4903 cdvdman_init();
4904 g_cdvdman_istruct.m_cd_inited = 1;
4905 }
4906 if ( mode == SCECdINIT )
4907 {
4908 u8 ready_status_tmp;
4909 u8 ready_status;
4910
4911 ready_status_tmp = 0;
4912 VERBOSE_PRINTF(1, "sceCdInit Ready check start.\n");
4913 ready_status = 0;
4914 while ( (ready_status & 0xC0) != 0x40 )
4915 {
4916#ifdef CDVD_VARIANT_XOSD
4917 if ( update_cd_mode_ps2_atapi() == 1 || sceCdGetDiskType() == 6 )
4918 break;
4919 g_cdvdman_istruct.m_field_0DC = 0;
4920 if ( sceCdGetDiskType() == SCECdNODISC )
4921 break;
4922#endif
4923 ready_status = sceCdDiskReady(8);
4924 vDelayThread(10000);
4925 if ( ready_status != ready_status_tmp )
4926 {
4927 ready_status_tmp = ready_status;
4928 VERBOSE_PRINTF(1, "sceCdInit Dev5 Status %x\n", ready_status);
4929 }
4930 // The following Kprintf was added for ioprp300x
4931 VERBOSE_PRINTF(1, "sceCdInit Ready check %x\n", ready_status);
4932 }
4933 VERBOSE_PRINTF(1, "sceCdInit Ready check end.\n");
4934 }
4935 g_cdvdman_istruct.m_wait_flag = 1;
4936 g_cdvdman_istruct.m_scmd_flag = 1;
4937 g_cdvdman_istruct.m_last_error = SCECdErNO;
4938 g_cdvdman_istruct.m_last_read_timeout = 0;
4939 g_cdvdman_spinctl = -1;
4940 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
4941 SetEventFlag(g_ncmd_evfid, 1);
4942 SetEventFlag(g_scmd_evfid, 1);
4943 SetEventFlag(g_sfile_evfid, 1);
4944 return 1;
4945}
4946
4947static int set_prev_command(int cmd, const char *sdata, int sdlen, char *rdata, int rdlen, int check_sef)
4948{
4949 int i;
4950 int delaybackoff;
4951 int j;
4952 u32 efbits;
4953#ifdef CDVD_VARIANT_XOSD
4954 int suspendres;
4955#endif
4956
4957#ifdef CDVD_VARIANT_XOSD
4958 {
4959 int state;
4960
4961 suspendres = CpuSuspendIntr(&state);
4962 CpuResumeIntr(state);
4963 suspendres = QueryIntrContext() || suspendres;
4964 }
4965 VERBOSE_KPRINTF(1, "set_prev_command cmd %02x call\n", cmd);
4966 if ( !suspendres )
4967 {
4968 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
4969 }
4970#endif
4971 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4972 {
4973 // The following Kprintf was added for ioprp300x
4974 VERBOSE_KPRINTF(1, "set_prev_command Double Booking\n");
4975#ifdef CDVD_VARIANT_XOSD
4976 if ( !suspendres )
4977 {
4978 SetEventFlag(g_cdvdman_csys_evfid, 1);
4979 }
4980#endif
4981 return 0;
4982 }
4983 g_cdvdman_istruct.m_scmd = cmd;
4984 g_cdvdman_istruct.m_sdlen = sdlen;
4985 g_cdvdman_istruct.m_rdlen = rdlen;
4986 for ( i = 0; i < sdlen; i += 1 )
4987 {
4988 g_cdvdman_istruct.m_scmd_sd[i] = sdata[i];
4989 }
4990#ifdef CDVD_VARIANT_XOSD
4991 if ( update_cd_mode_ps2_atapi() != 1 )
4992#endif
4993 {
4994 if ( g_cdvdman_istruct.m_wait_flag )
4995 {
4996 g_cdvdman_istruct.m_scmd_flag = 1;
4997 cdvdman_write_scmd(&g_cdvdman_istruct);
4998 }
4999 else if ( QueryIntrContext() )
5000 {
5001 while ( (dmac_ch_get_chcr(3) & 0x1000000) && !g_cdvdman_istruct.m_wait_flag )
5002 {
5003 VERBOSE_KPRINTF(1, "set_prev_command: DMA Wait\n");
5004 }
5005 g_cdvdman_istruct.m_scmd_flag = 1;
5006 cdvdman_write_scmd(&g_cdvdman_istruct);
5007 }
5008 else
5009 {
5010 g_cdvdman_istruct.m_scmd_flag = 0;
5011 }
5012 }
5013#ifdef CDVD_VARIANT_XOSD
5014 else
5015 {
5016 if ( !suspendres )
5017 {
5018 if ( g_cd_atapi_evfid != -1 )
5019 {
5020 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
5021 }
5022 if ( g_adma_evfid != -1 )
5023 {
5024 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5025 }
5026 if ( g_acmd_evfid != -1 )
5027 {
5028 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5029 }
5030 }
5031 {
5032 int state;
5033
5034 CpuSuspendIntr(&state);
5035 set_cdvd_dev5_base_addr_atapi(2);
5036 g_cdvdman_istruct.m_scmd_flag = 1;
5037 VERBOSE_KPRINTF(1, "do_set_prev_command %02x\n", cmd);
5038 cdvdman_write_scmd(&g_cdvdman_istruct);
5039 set_cdvd_dev5_base_addr_atapi(1);
5040 CpuResumeIntr(state);
5041 }
5042 if ( !suspendres )
5043 {
5044 if ( g_acmd_evfid != -1 )
5045 {
5046 SetEventFlag(g_acmd_evfid, 1);
5047 }
5048 if ( g_adma_evfid != -1 )
5049 {
5050 SetEventFlag(g_adma_evfid, 1);
5051 }
5052 if ( g_cd_atapi_evfid != -1 )
5053 {
5054 SetEventFlag(g_cd_atapi_evfid, 3);
5055 }
5056 }
5057 }
5058#endif
5059 delaybackoff = 1;
5060 for ( i = 0; i < 500; i += delaybackoff )
5061 {
5062 if ( g_cdvdman_istruct.m_scmd_flag )
5063 {
5064 for ( j = 0; j < rdlen; j += 1 )
5065 {
5066 rdata[j] = g_cdvdman_istruct.m_scmd_rd[j];
5067 }
5068 if ( check_sef == 1 )
5069 {
5070 vSetEventFlag(g_scmd_evfid, 1);
5071 }
5072#ifdef CDVD_VARIANT_XOSD
5073 VERBOSE_KPRINTF(1, "set_prev_command end :%02x\n", (u8)g_cdvdman_istruct.m_scmd);
5074 if ( !suspendres )
5075 {
5076 SetEventFlag(g_cdvdman_csys_evfid, 1);
5077 }
5078#endif
5079 return (u8)g_cdvdman_istruct.m_scmd;
5080 }
5081 vDelayThread(1000 * delaybackoff);
5082 if ( (i & 1) && delaybackoff < 16 )
5083 {
5084 delaybackoff *= 2;
5085 }
5086 }
5087 g_cdvdman_istruct.m_scmd_flag = 1;
5088 if ( check_sef == 1 )
5089 {
5090 vSetEventFlag(g_scmd_evfid, 1);
5091 }
5092 return 0;
5093}
5094
5095static void cdvdman_write_scmd(cdvdman_internal_struct_t *s)
5096{
5097 int i;
5098 unsigned int j;
5099 unsigned int rdcnt;
5100 char rdptr1[64];
5101 USE_DEV5_MMIO_HWPORT();
5102
5103 // The following Kprintf was added for ioprp300x
5104 VERBOSE_KPRINTF(1, "in:%d out_size:%d \n", (u8)s->m_sdlen, (u8)s->m_rdlen);
5105 // The following Kprintf was added for ioprp300x
5106 VERBOSE_KPRINTF(1, "cmd:%02x pram:%02x\n", (u8)s->m_scmd, (u8)s->m_scmd_sd[0]);
5107 for ( i = 0; i <= 0; i += 1 )
5108 {
5109 int overflowcond;
5110#ifdef CDVD_VARIANT_XOSD
5111 int suspendres;
5112#endif
5113
5114 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5115 {
5116 s->m_scmd_flag = 1;
5117 s->m_scmd = 0;
5118 // The following Kprintf was added for ioprp300x
5119 VERBOSE_KPRINTF(1, "do_set_prev_command BUSY ABNORM END %08x\n", dev5_mmio_hwport->m_dev5_reg_017);
5120 return;
5121 }
5122 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5123 {
5124 ;
5125 }
5126 for ( j = 0; j < (u8)s->m_sdlen; j += 1 )
5127 {
5128 dev5_mmio_hwport->m_dev5_reg_017 = s->m_scmd_sd[j];
5129 }
5130 dev5_mmio_hwport->m_dev5_reg_016 = s->m_scmd;
5131#ifdef CDVD_VARIANT_XOSD
5132 {
5133 int state;
5134 suspendres = CpuSuspendIntr(&state);
5135 CpuResumeIntr(state);
5136 suspendres = QueryIntrContext() || suspendres;
5137 }
5138#endif
5139#ifdef CDVD_VARIANT_XOSD
5140 if ( suspendres )
5141#else
5142 if ( QueryIntrContext() )
5143#endif
5144 {
5145 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
5146 {
5147 if ( j > 12500000 )
5148 {
5149 s->m_scmd_flag = 1;
5150 s->m_scmd = 0;
5151 return;
5152 }
5153 }
5154 }
5155 else
5156 {
5157 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
5158 {
5159 DelayThread(100);
5160 if ( j > 50000 )
5161 {
5162 // The following Kprintf was added for ioprp300x
5163 VERBOSE_KPRINTF(1, "Mecacon Scmd TIMEOUT CMD= %02x\n", (u8)s->m_scmd);
5164 s->m_scmd_flag = 1;
5165 s->m_scmd = 0;
5166 return;
5167 }
5168 }
5169 }
5170 overflowcond = 0;
5171 for ( j = 0; j < (u8)s->m_rdlen; j += 1 )
5172 {
5173 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5174 {
5175 break;
5176 }
5177 rdptr1[j] = dev5_mmio_hwport->m_dev5_reg_018;
5178 }
5179 if ( j >= (u8)s->m_rdlen )
5180 {
5181 overflowcond = 1;
5182 VERBOSE_KPRINTF(1, "Prev Cmd Result Over Flow\n", rdptr1);
5183 }
5184 rdcnt = j;
5185 if ( (!overflowcond && j >= (u8)s->m_rdlen) || s->m_rdlen == 16 )
5186 {
5187 break;
5188 }
5189 VERBOSE_KPRINTF(1, "Prev Cmd Result Illegal Size Try count:%d\n", i);
5190 }
5191 if ( i == 1 )
5192 {
5193 s->m_scmd_flag = 1;
5194 s->m_scmd = 0;
5195 }
5196 else
5197 {
5198 for ( j = 0; j < (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])); j += 1 )
5199 {
5200 s->m_scmd_rd[j] = 0;
5201 }
5202 if ( s->m_rdlen != (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])) )
5203 {
5204 rdcnt = (u8)s->m_rdlen;
5205 }
5206 for ( j = 0; j < rdcnt; j += 1 )
5207 {
5208 s->m_scmd_rd[j] = rdptr1[j];
5209 }
5210 s->m_scmd_flag = 1;
5211 s->m_scmd = 1;
5212 }
5213}
5214
5215#ifdef CDVD_VARIANT_XOSD
5216static int cdvdman_write_scmd_swap_dev5(char cmd, const char *wdata, int sdlen, char *rdata, int rdlen, int check_sef)
5217{
5218 int atapi_check;
5219 int i;
5220 int j;
5221 char rdstart[64];
5222 u32 efbits;
5223 int state;
5224 USE_DEV5_MMIO_HWPORT();
5225
5226 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5227 {
5228 return 0;
5229 }
5230 CpuSuspendIntr(&state);
5231 atapi_check = update_cd_mode_ps2_atapi() == 1;
5232 if ( atapi_check )
5233 {
5234 set_cdvd_dev5_base_addr_atapi(2);
5235 }
5236 for ( i = 0; i <= 0; i += 1 )
5237 {
5238 int cmdresoverflow;
5239
5240 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5241 {
5242 if ( atapi_check )
5243 {
5244 set_cdvd_dev5_base_addr_atapi(1);
5245 }
5246 CpuResumeIntr(state);
5247 if ( check_sef == 1 )
5248 {
5249 vSetEventFlag(g_scmd_evfid, 1);
5250 }
5251 return 0;
5252 }
5253 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5254 {
5255 ;
5256 }
5257 for ( j = 0; j < sdlen; j += 1 )
5258 {
5259 dev5_mmio_hwport->m_dev5_reg_017 = wdata[j];
5260 }
5261 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
5262 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5263 {
5264 ;
5265 }
5266 cmdresoverflow = 0;
5267 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
5268 {
5269 if ( j >= rdlen )
5270 {
5271 cmdresoverflow = 1;
5272 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Over Flow\n");
5273 break;
5274 }
5275 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
5276 }
5277 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
5278 {
5279 break;
5280 }
5281 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Illegal Size Try count:%d\n", i);
5282 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
5283 {
5284 ;
5285 }
5286 for ( j = 0; j < 16 - rdlen; j += 1 )
5287 {
5288 }
5289 }
5290 if ( i == 1 )
5291 {
5292 if ( atapi_check )
5293 {
5294 set_cdvd_dev5_base_addr_atapi(1);
5295 }
5296 CpuResumeIntr(state);
5297 if ( check_sef == 1 )
5298 {
5299 vSetEventFlag(g_scmd_evfid, 1);
5300 }
5301 return 0;
5302 }
5303 for ( j = 0; j < rdlen; j += 1 )
5304 {
5305 rdata[j] = rdstart[j];
5306 }
5307 if ( atapi_check )
5308 {
5309 set_cdvd_dev5_base_addr_atapi(1);
5310 }
5311 CpuResumeIntr(state);
5312 if ( check_sef == 1 )
5313 {
5314 vSetEventFlag(g_scmd_evfid, 1);
5315 }
5316 return 1;
5317}
5318#endif
5319
5320static int cdvdman_send_scmd2(int cmd, const void *sdata, int sdlen, void *rdata, int rdlen, int check_sef)
5321{
5322 int i;
5323 int j;
5324 char rdstart[64];
5325 u32 efbits;
5326 USE_DEV5_MMIO_HWPORT();
5327
5328 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5329 {
5330 return 0;
5331 }
5332 for ( i = 0; i <= 0; i += 1 )
5333 {
5334 int cmdresoverflow;
5335
5336 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5337 {
5338 if ( check_sef == 1 )
5339 {
5340 vSetEventFlag(g_scmd_evfid, 1);
5341 }
5342 return 0;
5343 }
5344 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5345 {
5346 ;
5347 }
5348 for ( j = 0; j < sdlen; j += 1 )
5349 {
5350 dev5_mmio_hwport->m_dev5_reg_017 = ((u8 *)sdata)[j];
5351 }
5352 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
5353 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5354 {
5355#ifndef CDVD_VARIANT_XOSD
5356 DelayThread(100);
5357#endif
5358 }
5359 cmdresoverflow = 0;
5360 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
5361 {
5362 if ( j >= rdlen )
5363 {
5364 cmdresoverflow = 1;
5365 // The following Kprintf was modified for ioprp300x
5366 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Over Flow\n");
5367 break;
5368 }
5369 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
5370 }
5371 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
5372 {
5373 break;
5374 }
5375 // The following Kprintf was modified for ioprp300x
5376 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Illegal Size Try count:%d\n", i);
5377 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
5378 {
5379 ;
5380 }
5381 for ( j = 0; j < 16 - rdlen; j += 1 )
5382 ;
5383 }
5384 if ( i == 1 )
5385 {
5386 if ( check_sef == 1 )
5387 {
5388 vSetEventFlag(g_scmd_evfid, 1);
5389 }
5390 return 0;
5391 }
5392 for ( i = 0; i < rdlen; i += 1 )
5393 {
5394 ((char *)rdata)[i] = rdstart[i];
5395 }
5396 if ( check_sef == 1 )
5397 {
5398 vSetEventFlag(g_scmd_evfid, 1);
5399 }
5400 return 1;
5401}
5402
5403#ifdef CDVD_VARIANT_OSD
5404static unsigned int signal_sema_timeout_callback(void *userdata)
5405{
5406 int sema_id;
5407
5408 sema_id = (int)(u32)(uiptr)userdata;
5409 iSignalSema(sema_id);
5410 return 0;
5411}
5412#endif
5413
5414int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
5415{
5416 int i;
5417
5418#ifdef CDVD_VARIANT_OSD
5419 if ( g_cdvdman_minver_50000 )
5420 {
5421 WaitSema(g_cdvdman_apply_scmd_sema);
5422 }
5423#endif
5424 for ( i = 0; i <= 2500; i += 1 )
5425 {
5426 if ( set_prev_command(cmdNum, (const char *)inBuff, inBuffSize, (char *)outBuff, 16, 1) )
5427 {
5428#ifdef CDVD_VARIANT_OSD
5429 if ( g_cdvdman_minver_50000 )
5430 {
5431 iop_sys_clock_t sysclk;
5432
5433 sysclk.hi = 0;
5434 sysclk.lo = 0x9000;
5435 SetAlarm(&sysclk, signal_sema_timeout_callback, (void *)g_cdvdman_apply_scmd_sema);
5436 }
5437 else
5438#endif
5439 {
5440 DelayThread(2000);
5441 }
5442 return 1;
5443 }
5444 DelayThread(2000);
5445 }
5446 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5447 return 0;
5448}
5449
5450int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
5451{
5452#ifdef CDVD_VARIANT_XOSD
5453 return sceCdApplySCmd(cmdNum, inBuff, inBuffSize, outBuff);
5454#else
5455 int i;
5456
5457 for ( i = 0; i <= 2500; i += 1 )
5458 {
5459 if ( cdvdman_send_scmd2(cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
5460 {
5461 return 1;
5462 }
5463 DelayThread(2000);
5464 }
5465 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5466 return 0;
5467#endif
5468}
5469
5470#ifdef CDVD_VARIANT_OSD
5471int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
5472{
5473 int i;
5474
5475 for ( i = 0; i <= 2500; i += 1 )
5476 {
5477 DelayThread(2000);
5478 if ( set_prev_command((u8)cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
5479 {
5480 DelayThread(2000);
5481 return 1;
5482 }
5483 }
5484 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5485 return 0;
5486}
5487#endif
5488
5489int sceCdBreak(void)
5490{
5491 u32 efbits;
5492 int state;
5493 int oldstate;
5494 USE_DEV5_MMIO_HWPORT();
5495
5496 if ( PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5497 {
5498 return 0;
5499 }
5500 CpuSuspendIntr(&state);
5501 // The following Kprintf was modified for ioprp300x
5502 VERBOSE_KPRINTF(
5503 1,
5504 "Break call: read2_flg= %d func= %d lsn= %d csec= %d nsec= %d %rsec= %d addr= %p waitflg= %d, DriveIntrReq= %d "
5505 "stmflg= %d recover= %d\n",
5506 g_cdvdman_istruct.m_read2_flag,
5507 g_cdvdman_cmdfunc,
5508 g_cdvdman_istruct.m_cdvdman_lsn,
5509 g_cdvdman_istruct.m_cdvdman_csec,
5510 g_cdvdman_istruct.m_cdvdman_nsec,
5511 g_cdvdman_istruct.m_cdvdman_rsec,
5512 g_cdvdman_istruct.m_read_buf,
5513 g_cdvdman_istruct.m_wait_flag,
5514 g_cdvdman_istruct.m_drive_interupt_request,
5515 g_cdvdman_istruct.m_stream_flag,
5516 g_cdvdman_istruct.m_recover_status);
5517 if ( g_cdvdman_istruct.m_last_read_timeout )
5518 {
5519 g_cdvdman_istruct.m_read2_flag = 0;
5520 }
5521 g_cdvdman_istruct.m_last_error = SCECdErABRT;
5522 g_cdvdman_istruct.m_thread_id = GetThreadId();
5523 g_cdvdman_istruct.m_break_cdvdfsv_readchain = 1;
5524 if ( g_cdvdman_istruct.m_dec_state )
5525 {
5526 g_cdvdman_istruct.m_dec_shift = 0;
5527 g_cdvdman_istruct.m_check_version = 0;
5528 g_cdvdman_istruct.m_dec_state = 0;
5529 sceCdDecSet(0, 0, 0);
5530 }
5531 g_cdvdman_istruct.m_recover_status = 0;
5532 if ( QueryIntrContext() )
5533 {
5534 iSetEventFlag(g_cdvdman_intr_evfid, 0x29);
5535 iCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5536 }
5537 else
5538 {
5539 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
5540 CancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5541 }
5542 if ( !g_cdvdman_istruct.m_wait_flag || g_cdvdman_istruct.m_last_read_timeout )
5543 {
5544 // The following direct register access was replaced with call for ioprp300x
5545 if ( (sceCdDiskReady(8) & 0xC0) == 0x40 )
5546 {
5547 VERBOSE_KPRINTF(1, "cdvd: NonInter END\n");
5548 g_cdvdman_istruct.m_wait_flag = 1;
5549 }
5550 g_cdvdman_last_cmdfunc = g_cdvdman_cmdfunc;
5551 g_cdvdman_cmdfunc = SCECdFuncBreak;
5552 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5553 if ( g_cdvdman_istruct.m_last_read_timeout )
5554 {
5555 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
5556 }
5557 g_cdvdman_istruct.m_drive_interupt_request = 0;
5558 VERBOSE_KPRINTF(1, "cdvd: Abort command On\n");
5559 }
5560 vSetEventFlag(g_ncmd_evfid, 1);
5561 CpuResumeIntr(state);
5562 return 1;
5563}
5564
5565static unsigned int ncmd_timeout_alarm_cb(void *userdata)
5566{
5567 iop_sys_clock_t *sys_clock;
5568
5569 sys_clock = (iop_sys_clock_t *)userdata;
5570 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
5571 sys_clock->lo = 0;
5572 return 0;
5573}
5574
5575static int intrh_dma_3(void *userdata)
5576{
5577 int dmacbres;
5578 int oldstate;
5580
5581 s = (cdvdman_internal_struct_t *)userdata;
5582 s->m_dma3_param.m_dma3_msectors -= s->m_dma3_param.m_dma3_csectors;
5583 // The following Kprintf was added for ioprp300x
5584 VERBOSE_KPRINTF(
5585 1,
5586 "_sceCdDmaIntr wk %d: func_num: %d nsec %d cnt %d cdid:%08x\n",
5587 s->m_wait_flag,
5588 g_cdvdman_cmdfunc,
5589 s->m_dma3_param.m_dma3_msectors,
5590 s->m_cdvdman_dma3sec,
5591 &g_cdvdman_istruct);
5592 dmacbres = s->m_dma3_param.m_dma3_callback ? s->m_dma3_param.m_dma3_callback() : 1;
5593 s->m_cdvdman_dma3sec += s->m_dma3_param.m_dma3_csectors;
5594 s->m_dma3_param.m_dma3_csectors = ((u32)s->m_read_chunk > (u32)s->m_dma3_param.m_dma3_msectors) ?
5595 (u32)s->m_dma3_param.m_dma3_msectors :
5596 (u32)s->m_read_chunk;
5597 if ( dmacbres )
5598 {
5599 if ( s->m_dma3_param.m_dma3_msectors )
5600 {
5601 dmac_ch_set_chcr(3, 0);
5602 dmac_ch_get_chcr(3);
5603 dmac_ch_set_madr(3, (u32)s->m_dma3_param.m_dma3_maddress);
5604 dmac_ch_set_bcr(
5605 3,
5606 ((s->m_dma3_param.m_dma3_blkcount * s->m_dma3_param.m_dma3_csectors) << 16) | s->m_dma3_param.m_dma3_blkwords);
5607 dmac_ch_set_chcr(3, 0x41000200);
5608 dmac_ch_get_chcr(3);
5609 iClearEventFlag(g_cdvdman_intr_evfid, ~0x20);
5610 }
5611 else
5612 {
5613 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
5614 iSetEventFlag(g_cdvdman_intr_evfid, 0x20);
5615 }
5616 }
5617 if ( !s->m_dma3_param.m_dma3_msectors && s->m_drive_interupt_request )
5618 {
5619 cdvdman_intr_cb(s);
5620 s->m_drive_interupt_request = 0;
5621 }
5622 return 1;
5623}
5624
5625static int cdvdman_setdma3(cdvdman_dma3_parameter_t *dma3_param)
5626{
5627 USE_DEV5_MMIO_HWPORT();
5628
5629 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
5630 {
5631 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5632 }
5633 g_cdvdman_istruct.m_drive_interupt_request = 0;
5634 g_cdvdman_istruct.m_dma3_param.m_dma3_blkwords = dma3_param->m_dma3_blkwords;
5635 g_cdvdman_istruct.m_dma3_param.m_dma3_blkcount = dma3_param->m_dma3_blkcount;
5636 g_cdvdman_istruct.m_dma3_param.m_dma3_maddress = dma3_param->m_dma3_maddress;
5637 g_cdvdman_istruct.m_dma3_param.m_dma3_callback = dma3_param->m_dma3_callback;
5638 g_cdvdman_istruct.m_dma3_param.m_dma3_csectors = dma3_param->m_dma3_csectors;
5639 g_cdvdman_istruct.m_dma3_param.m_cdvdreg_howto = dma3_param->m_cdvdreg_howto;
5640 g_cdvdman_istruct.m_dma3_param.m_dma3_msectors = dma3_param->m_dma3_msectors;
5641 g_cdvdman_istruct.m_cdvdman_dma3sec = 0;
5642 dmac_ch_set_chcr(3, 0);
5643 dmac_ch_get_chcr(3);
5644 if ( dma3_param->m_dma3_csectors )
5645 {
5646 vClearEventFlag(g_cdvdman_intr_evfid, ~0x20);
5647 EnableIntr(IOP_IRQ_DMA_CDVD);
5648 }
5649 dev5_mmio_hwport->m_dev5_reg_006 = dma3_param->m_cdvdreg_howto;
5650 dmac_ch_set_madr(3, (u32)dma3_param->m_dma3_maddress);
5651 dmac_ch_set_bcr(
5652 3,
5653 (dma3_param->m_dma3_blkcount * (dma3_param->m_dma3_csectors ? dma3_param->m_dma3_csectors : 1)) << 16
5654 | dma3_param->m_dma3_blkwords);
5655 dmac_ch_set_chcr(3, 0x41000200);
5656 return dmac_ch_get_chcr(3);
5657}
5658
5659#ifdef CDVD_VARIANT_XOSD
5660static int update_cd_mode_ps2_atapi(void)
5661{
5662 int is_intr_context;
5663 int saved_cd_mode_ps2_atapi;
5664 int state;
5665
5666 is_intr_context = !QueryIntrContext();
5667 if ( is_intr_context )
5668 {
5669 CpuSuspendIntr(&state);
5670 }
5671 saved_cd_mode_ps2_atapi = g_cdvdman_istruct.m_cd_mode_ps2_atapi;
5672 if ( saved_cd_mode_ps2_atapi == 1 )
5673 {
5674 if ( !(*g_cdvdreg_bf801460 & 2) || (unsigned int)GetBaseAddress(5) != (unsigned int)0xBF410000 )
5675 {
5676 set_cdvd_dev5_base_addr_atapi(1);
5677 }
5678 }
5679 else
5680 {
5681 if ( (*g_cdvdreg_bf801460 & 2) || (unsigned int)GetBaseAddress(5) != (unsigned int)0x1F402000 )
5682 {
5683 set_cdvd_dev5_base_addr_atapi(2);
5684 }
5685 }
5686 if ( is_intr_context )
5687 {
5688 CpuResumeIntr(state);
5689 }
5690 return saved_cd_mode_ps2_atapi;
5691}
5692#endif
5693
5694#ifdef CDVD_VARIANT_XOSD
5695static int set_cdvd_dev5_base_addr_atapi(int mode)
5696{
5697 int is_intr_context;
5698 int state;
5699
5700 is_intr_context = !QueryIntrContext();
5701 if ( is_intr_context )
5702 {
5703 CpuSuspendIntr(&state);
5704 }
5705 if ( mode == 1 )
5706 {
5707 SetBaseAddress(5, 0xBF410000);
5708 VERBOSE_KPRINTF(1, "DEV5-addr : 0x%08lx\n", GetBaseAddress(5));
5709 SetDelay(5, 0xEF101043);
5710 VERBOSE_KPRINTF(1, "DEV5-dely : 0x%08lx\n", GetDelay(5));
5711 *g_cdvdreg_bf801464 |= 0xC;
5712 *g_cdvdreg_bf801460 |= 0x40;
5713 *g_cdvdreg_bf801460 |= 2;
5714 }
5715 else
5716 {
5717 SetBaseAddress(5, 0x1F402000);
5718 VERBOSE_KPRINTF(1, "DEV5-addr : 0x%08lx\n", GetBaseAddress(5));
5719 SetDelay(5, 0x6F060011);
5720 VERBOSE_KPRINTF(1, "DEV5-dely : 0x%08lx\n", GetDelay(5));
5721 *g_cdvdreg_bf801460 &= ~2;
5722 *g_cdvdreg_bf801460 &= ~0x40;
5723 *g_cdvdreg_bf801464 &= 0xF3;
5724 }
5725 if ( is_intr_context )
5726 {
5727 CpuResumeIntr(state);
5728 }
5729 return 1;
5730}
5731#endif
5732
5733#ifdef CDVD_VARIANT_XOSD
5734static int cdvdman_change_drive(int mode)
5735{
5736 ClearEventFlag(g_cdvdman_csys_evfid, ~1);
5737 if ( mode == 1 )
5738 {
5739 VERBOSE_KPRINTF(1, "Init Go SCECdChgWriDrv\n");
5740 ClearEventFlag(g_fio_fsv_evfid, ~1);
5741 ClearEventFlag(g_sfile_evfid, ~1);
5742 ClearEventFlag(g_scmd_evfid, ~1);
5743 ClearEventFlag(g_ncmd_evfid, ~1);
5744 set_cdvd_dev5_base_addr_atapi(1);
5745 if ( g_cd_atapi_evfid != -1 )
5746 {
5747 SetEventFlag(g_cd_atapi_evfid, 3);
5748 }
5749 if ( g_adma_evfid != -1 )
5750 {
5751 SetEventFlag(g_adma_evfid, 1);
5752 }
5753 if ( g_acmd_evfid != -1 )
5754 {
5755 SetEventFlag(g_acmd_evfid, 1);
5756 }
5757 SetEventFlag(g_scmd_evfid, 1);
5758 VERBOSE_KPRINTF(1, "Init Go SCECdChgWriDrv End.\n");
5759 SetEventFlag(g_fio_fsv_evfid, 1);
5760 }
5761 else
5762 {
5763 VERBOSE_KPRINTF(1, "Init Go SCECdChgPs2Drv\n");
5764 ClearEventFlag(g_scmd_evfid, ~1);
5765 if ( g_acmd_evfid != -1 )
5766 {
5767 ClearEventFlag(g_acmd_evfid, ~1);
5768 }
5769 if ( g_adma_evfid != -1 )
5770 {
5771 ClearEventFlag(g_adma_evfid, ~1);
5772 }
5773 if ( g_cd_atapi_evfid != -1 )
5774 {
5775 ClearEventFlag(g_cd_atapi_evfid, ~3);
5776 }
5777 set_cdvd_dev5_base_addr_atapi(mode);
5778 SetEventFlag(g_ncmd_evfid, 1);
5779 SetEventFlag(g_scmd_evfid, 1);
5780 SetEventFlag(g_sfile_evfid, 1);
5781 SetEventFlag(g_fio_fsv_evfid, 1);
5782 VERBOSE_KPRINTF(1, "Init Go SCECdChgPs2Drv End.\n");
5783 }
5784 SetEventFlag(g_cdvdman_csys_evfid, 1);
5785 return 1;
5786}
5787#endif
5788
5789#ifdef CDVD_VARIANT_XOSD
5790// cppcheck-suppress funcArgNamesDifferent
5791int sceCdChgSys(u32 use_writer_drive)
5792{
5793 int current_mode;
5794 u32 efbits;
5795 USE_DEV5_MMIO_HWPORT();
5796
5797 VERBOSE_KPRINTF(1, "sceCdChgSys(%d) start.\n", use_writer_drive);
5798 if ( QueryIntrContext() )
5799 {
5800 return 0;
5801 }
5802 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5803 current_mode = update_cd_mode_ps2_atapi();
5804 VERBOSE_KPRINTF(
5805 1, "sceCdChgSys %d call mode:%d->%d\n", use_writer_drive, current_mode, g_cdvdman_istruct.m_cd_mode_ps2_atapi);
5806 if ( !use_writer_drive )
5807 {
5808 g_cdvdman_istruct.m_cd_mode_ps2_atapi = current_mode;
5809 }
5810 if (
5811 use_writer_drive
5812 && (use_writer_drive != (u32)current_mode || g_cdvdman_istruct.m_cd_mode_ps2_atapi != current_mode) )
5813 {
5814 int disc_type;
5815
5816 if ( use_writer_drive == 1 )
5817 {
5818 VERBOSE_KPRINTF(1, "Go SCECdChgWriDrv\n");
5819 VERBOSE_KPRINTF(1, "fio_fsv_evfid\n");
5820 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5821 VERBOSE_KPRINTF(1, "sfile_evfid\n");
5822 WaitEventFlag(g_sfile_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5823 VERBOSE_KPRINTF(1, "sceCdSync\n");
5824 sceCdSync(0);
5825 VERBOSE_KPRINTF(1, "scmd_evfid\n");
5826 WaitEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5827 VERBOSE_KPRINTF(1, "ncmd_evfid\n");
5828 WaitEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5829 set_cdvd_dev5_base_addr_atapi(2);
5830 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5831 if ( g_cdvdman_vernotxxx1x )
5832 {
5833 if ( (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5834 {
5835 g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open = 1;
5836 }
5837 if (
5838 (!(dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen))
5839 || (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5840 {
5841 int last_err;
5842
5843 last_err = 2;
5844 while ( last_err != SCECdErNO && last_err != SCECdErABRT )
5845 {
5846 VERBOSE_KPRINTF(1, "GO->Atapi sceCdChgSpdlCtrl Call %d\n", 0);
5847 while ( !sceCdChgSpdlCtrl(0) )
5848 {
5849 DelayThread(16000);
5850 }
5851 sceCdSync(3);
5852 last_err = sceCdGetError();
5853 if ( last_err != SCECdErNO )
5854 {
5855 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl ERR 0x%02x\n", last_err);
5856 DelayThread(250000);
5857 }
5858 }
5859 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl OK\n", last_err);
5860 }
5861 }
5862 set_cdvd_dev5_base_addr_atapi(1);
5863 g_cdvdman_istruct.m_cd_mode_ps2_atapi = 1;
5864 if (
5865 g_cdvdman_vernotxxx1x && disc_type != SCECdNODISC && g_cdvdman_istruct.m_chgsys_callback_next_disktype_last
5866 && g_cdvdman_istruct.m_chgsys_callback )
5867 {
5868 int i;
5869
5870 for ( i = 0;
5871 i < 10 && g_cdvdman_istruct.m_chgsys_callback(&g_cdvdman_istruct.m_chgsys_callback_next_disktype, 1);
5872 i += 1 )
5873 {
5874 DelayThread(16000);
5875 }
5876 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = SCECdNODISC;
5877 }
5878 if ( g_cd_atapi_evfid != -1 )
5879 {
5880 SetEventFlag(g_cd_atapi_evfid, 3);
5881 }
5882 if ( g_adma_evfid != -1 )
5883 {
5884 SetEventFlag(g_adma_evfid, 1);
5885 }
5886 if ( g_acmd_evfid != -1 )
5887 {
5888 SetEventFlag(g_acmd_evfid, 1);
5889 }
5890 SetEventFlag(g_scmd_evfid, 1);
5891 SetEventFlag(g_fio_fsv_evfid, 1);
5892 VERBOSE_KPRINTF(1, "Go SCECdChgWriDrv End.\n");
5893 }
5894 else
5895 {
5896 VERBOSE_KPRINTF(1, "Go SCECdChgPs2Drv\n");
5897 VERBOSE_KPRINTF(1, "scmd_evfid\n");
5898 WaitEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5899 if ( g_acmd_evfid != -1 )
5900 {
5901 VERBOSE_KPRINTF(1, "g_acmd_evfid Wait\n");
5902 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5903 }
5904 if ( g_adma_evfid != -1 )
5905 {
5906 VERBOSE_KPRINTF(1, "g_adma_evfid Wait\n");
5907 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5908 }
5909 if ( g_cd_atapi_evfid != -1 )
5910 {
5911 VERBOSE_KPRINTF(1, "g_cd_atapi_evfid Wait\n");
5912 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
5913 }
5914 VERBOSE_KPRINTF(1, "evflg Ok\n");
5915 set_cdvd_dev5_base_addr_atapi(1);
5916 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5917 if ( g_cdvdman_vernotxxx1x )
5918 {
5919 set_cdvd_dev5_base_addr_atapi(2);
5920 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5921 set_cdvd_dev5_base_addr_atapi(1);
5922 VERBOSE_KPRINTF(1, "GO->PS2 STOP ATAPI SPINDL\n");
5923 if ( disc_type == 6 && g_cdvdman_istruct.m_chgsys_callback )
5924 {
5925 int i;
5926
5927 for ( i = 0;
5928 i < 10 && g_cdvdman_istruct.m_chgsys_callback(&g_cdvdman_istruct.m_chgsys_callback_next_disktype, 0);
5929 i += 1 )
5930 {
5931 DelayThread(16000);
5932 }
5933 if ( i == 10 )
5934 {
5935 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5936 }
5937 VERBOSE_KPRINTF(1, "Atapi Set -> Dragon Media %d\n", g_cdvdman_istruct.m_chgsys_callback_next_disktype);
5938 if ( g_cdvdman_istruct.m_chgsys_callback_next_disktype == 256 )
5939 {
5940 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = g_cdvdman_istruct.m_chgsys_callback_next_disktype;
5941 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5942 }
5943 }
5944 }
5945 set_cdvd_dev5_base_addr_atapi(use_writer_drive);
5946 g_cdvdman_istruct.m_cd_mode_ps2_atapi = use_writer_drive;
5947 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5948 if ( g_cdvdman_vernotxxx1x )
5949 {
5950 if (
5951 ((dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen))
5952 || (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5953 {
5954 int last_err;
5955
5956 last_err = 2;
5957 while ( last_err != SCECdErNO && last_err != SCECdErABRT && last_err != SCECdErPRM )
5958 {
5959 if ( (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5960 {
5961 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCT;
5962 }
5963 VERBOSE_KPRINTF(
5964 1,
5965 "GO->DRAGON sceCdChgSpdlCtrl Call %d Ps2MediaType %02x\n",
5966 g_cdvdman_istruct.m_chgsys_callback_next_disktype,
5967 disc_type);
5968 while ( !sceCdChgSpdlCtrl(g_cdvdman_istruct.m_chgsys_callback_next_disktype) )
5969 {
5970 DelayThread(16000);
5971 }
5972 sceCdSync(3);
5973 last_err = sceCdGetError();
5974 if ( last_err != SCECdErNO )
5975 {
5976 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl ERR 0x%02x\n", last_err);
5977 DelayThread(250000);
5978 }
5979 }
5980 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl OK\n");
5981 }
5982 }
5983 else
5984 {
5985 VERBOSE_KPRINTF(1, " -> Ps2 May be No media %08x\n", disc_type);
5986 }
5987 SetEventFlag(g_ncmd_evfid, 1);
5988 SetEventFlag(g_scmd_evfid, 1);
5989 SetEventFlag(g_sfile_evfid, 1);
5990 SetEventFlag(g_fio_fsv_evfid, 1);
5991 VERBOSE_KPRINTF(1, "Go SCECdChgPs2Drv End.\n");
5992 }
5993 }
5994 SetEventFlag(g_cdvdman_csys_evfid, 1);
5995 return current_mode;
5996}
5997#endif
5998
5999static int
6000cdvdman_send_ncmd(int ncmd, const void *ndata, int ndlen, int func, cdvdman_dma3_parameter_t *dma3_param, int check_cb)
6001{
6002 int i;
6003 u32 efbits;
6004 USE_DEV5_MMIO_HWPORT();
6005
6006 if ( check_cb == 1 && PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6007 {
6008 return -1;
6009 }
6010 if (
6011 // The following direct register access was replaced with call for ioprp300x
6012 (sceCdDiskReady(8) & 0xC0) != 0x40 || !g_cdvdman_istruct.m_wait_flag
6013 || !(g_cdvdman_istruct.m_read2_flag != 1 || ncmd == 8) || !(g_cdvdman_istruct.m_read2_flag != 2 || ncmd == 6) )
6014 {
6015 if ( check_cb == 1 )
6016 {
6017 vSetEventFlag(g_ncmd_evfid, 1);
6018 }
6019 // The following direct register access was replaced with call for ioprp300x
6020 VERBOSE_KPRINTF(1, "set_cd_commnad Error\tstat %02x\n", (u8)sceCdDiskReady(8));
6021 return -1;
6022 }
6023 g_cdvdman_iocache = 0;
6024 if ( dma3_param )
6025 {
6026 cdvdman_setdma3(dma3_param);
6027 }
6028 g_cdvdman_cmdfunc = func;
6029 // The following call to sceCdGetDiskType was inlined
6030 if (
6031 !g_cdvdman_minver_10700 && g_cdvdman_ncmd == 0x06 && ncmd && ncmd != g_cdvdman_ncmd && ncmd != 0x07 && ncmd != 0x0E
6032 && ncmd != 0x08
6033#ifdef CDVD_VARIANT_XOSD
6034 && ncmd != 0x0C
6035#endif
6036 && (sceCdGetDiskType() != SCECdCDDA || ncmd == 0x03) )
6037 {
6038 g_cdvdman_ncmd_timeout.hi = 0;
6039 g_cdvdman_ncmd_timeout.lo = 0x6978000;
6040 vSetAlarm(&g_cdvdman_ncmd_timeout, ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
6041 while ( dev5_mmio_hwport->m_dev5_reg_00A != SCECdStatPause )
6042 {
6043 VERBOSE_KPRINTF(1, "Read Pause 1 chk status 0x%02x\n", dev5_mmio_hwport->m_dev5_reg_00A);
6044 if ( !g_cdvdman_ncmd_timeout.lo )
6045 {
6046 g_cdvdman_ncmd = ncmd;
6047 if ( check_cb == 1 )
6048 {
6049 vSetEventFlag(g_ncmd_evfid, 1);
6050 }
6051 KPRINTF("Time Out Pause WAIT set_cd_commnad\n");
6052 return -1;
6053 }
6054 vDelayThread(1000);
6055 }
6056 vCancelAlarm(ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
6057 }
6058 g_cdvdman_ncmd = ncmd;
6059 if ( g_cdvdman_istruct.m_dec_state )
6060 {
6061 sceCdDecSet(!!g_cdvdman_istruct.m_dec_shift, 1, g_cdvdman_istruct.m_dec_shift);
6062 }
6063 g_cdvdman_istruct.m_last_read_timeout = 0;
6064 g_cdvdman_istruct.m_cdvdman_command = ncmd;
6065 g_cdvdman_istruct.m_last_error = SCECdErNO;
6066 g_cdvdman_istruct.m_wait_flag = 0;
6067 g_cdvdman_istruct.m_thread_id = GetThreadId();
6068 if ( QueryIntrContext() )
6069 {
6070 iClearEventFlag(g_cdvdman_intr_evfid, ~1);
6071 }
6072 else
6073 {
6074 ClearEventFlag(g_cdvdman_intr_evfid, ~1);
6075 }
6076 for ( i = 0; i < ndlen; i += 1 )
6077 {
6078 dev5_mmio_hwport->m_dev5_reg_005 = ((u8 *)ndata)[i];
6079 }
6080 dev5_mmio_hwport->m_dev5_reg_004 = ncmd;
6081 if ( check_cb == 1 )
6082 {
6083 vSetEventFlag(g_ncmd_evfid, 1);
6084 }
6085 return 0;
6086}
6087
6088int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
6089{
6090 VERBOSE_KPRINTF(1, "Apply NCmd call cmd= 0x%02x\n", cmdNum);
6091 while ( cdvdman_send_ncmd(cmdNum, inBuff, inBuffSize, 0, 0, 1) < 0 )
6092 {
6093 vDelayThread(2000);
6094 }
6095 sceCdSync(4);
6096 return 1;
6097}
6098
6099int sceCdCheckCmd(void)
6100{
6101 return g_cdvdman_istruct.m_wait_flag;
6102}
6103
6104static int cdvdman_mediactl(int code)
6105{
6106 int reg_00B_tmp_1;
6107 int retval;
6108 u32 efbits;
6109 char rdata[1];
6110#ifndef CDVD_VARIANT_XOSD
6111 USE_DEV5_MMIO_HWPORT();
6112#endif
6113
6114 rdata[0] = 0;
6115 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6116 {
6117 return 0;
6118 }
6119#ifdef CDVD_VARIANT_XOSD
6120 reg_00B_tmp_1 = get_cdvd_register(0x0B) & SCECdStatShellOpen;
6121#else
6122 reg_00B_tmp_1 = dev5_mmio_hwport->m_dev5_reg_00B & SCECdStatShellOpen;
6123#endif
6124 if ( reg_00B_tmp_1 == g_cdvdman_chmedia )
6125 {
6126 retval = 0;
6127 if ( g_cdvdman_chflags[code] )
6128 {
6129 g_cdvdman_chflags[code] = 0;
6130 retval = 1;
6131 }
6132 }
6133 else
6134 {
6135 unsigned int i;
6136
6137 for ( i = 0; i < (sizeof(g_cdvdman_chflags) / sizeof(g_cdvdman_chflags[0])); i += 1 )
6138 {
6139 g_cdvdman_chflags[i] = i != (unsigned int)code;
6140 }
6141 retval = 1;
6142 }
6143#ifdef CDVD_VARIANT_XOSD
6144 if ( ((get_cdvd_register(0x0A)) & SCECdStatShellOpen) != reg_00B_tmp_1 )
6145#else
6146 if ( ((dev5_mmio_hwport->m_dev5_reg_00A) & SCECdStatShellOpen) != reg_00B_tmp_1 )
6147#endif
6148 {
6149 while ( !set_prev_command(0x05, NULL, 0, rdata, sizeof(rdata), 0) || rdata[0] )
6150 {
6151 vDelayThread(4000);
6152 }
6153 }
6154#ifdef CDVD_VARIANT_XOSD
6155 g_cdvdman_chmedia = get_cdvd_register(0x0B) & 1;
6156#else
6157 g_cdvdman_chmedia = dev5_mmio_hwport->m_dev5_reg_00B & SCECdStatShellOpen;
6158#endif
6159 vSetEventFlag(g_scmd_evfid, 1);
6160 return retval;
6161}
6162
6163int sceCdGetError(void)
6164{
6165 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
6166 {
6167 VERBOSE_KPRINTF(1, "sceCdGetError: 0x%02x\n", (u8)g_cdvdman_istruct.m_last_error);
6168 }
6169 return (u8)g_cdvdman_istruct.m_last_error;
6170}
6171
6172#ifdef DEAD_CODE
6173int cdvdman_get_last_command(void)
6174{
6175 return (u8)g_cdvdman_istruct.m_cdvdman_command;
6176}
6177#endif
6178
6179int sceCdNop(void)
6180{
6181 return cdvdman_send_ncmd(0x00, NULL, 0, 0, 0, 1) >= 0;
6182}
6183
6184#ifdef DEAD_CODE
6185int cdvdman_ncmd_sender_01(void)
6186{
6187 return cdvdman_send_ncmd(0x01, NULL, 0, 0, 0, 1) >= 0;
6188}
6189#endif
6190
6191#ifndef CDVD_VARIANT_XOSD
6192static int cdvdman_ncmd_sender_06(void)
6193{
6194 int i;
6195 cdvdman_dma3_parameter_t dma3_param;
6196 char ndata[11];
6197
6198 // The following call to sceCdGetDiskType was inlined
6199 if ( sceCdGetDiskType() == SCECdNODISC )
6200 {
6201 return 1;
6202 }
6203 for ( i = 0; i < 48; i += 8 )
6204 {
6205 // The following Kprintf was removed for ioprp300x
6206 KPRINTF("CMD_READP call\n");
6207 ndata[0] = i + 17;
6208 ndata[3] = 0;
6209 ndata[2] = 0;
6210 ndata[1] = 0;
6211 ndata[4] = 8;
6212 ndata[7] = 0;
6213 ndata[6] = 0;
6214 ndata[5] = 0;
6215 ndata[8] = 0;
6216 ndata[9] = 1;
6217 ndata[10] = 0;
6218 dma3_param.m_cdvdreg_howto = 128;
6219 dma3_param.m_dma3_blkwords = 32;
6220 dma3_param.m_dma3_blkcount = 128;
6221 dma3_param.m_dma3_csectors = 0;
6222 dma3_param.m_dma3_msectors = 0;
6223 dma3_param.m_dma3_callback = 0;
6224 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
6225 if ( cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 5, &dma3_param, 1) < 0 )
6226 {
6227 return 0;
6228 }
6229 sceCdSync(3);
6230 }
6231 return 1;
6232}
6233#endif
6234
6235int sceCdStandby(void)
6236{
6237 cdvdman_dma3_parameter_t dma3_param;
6238 char ndata[11];
6239
6240#ifdef CDVD_VARIANT_XOSD
6241 switch ( get_disk_type_ex() )
6242#else
6243 // The following call to sceCdGetDiskType was inlined
6244 switch ( sceCdGetDiskType() )
6245#endif
6246 {
6247 case SCECdPSCD:
6248 case SCECdPSCDDA:
6249 case SCECdPS2CD:
6250 case SCECdPS2CDDA:
6251 case SCECdPS2DVD:
6252 ndata[0] = 16;
6253 ndata[4] = 1;
6254 ndata[9] = 1;
6255 dma3_param.m_cdvdreg_howto = 128;
6256 dma3_param.m_dma3_blkwords = 32;
6257 dma3_param.m_dma3_blkcount = 16;
6258 ndata[3] = 0;
6259 ndata[2] = 0;
6260 ndata[1] = 0;
6261 ndata[7] = 0;
6262 ndata[6] = 0;
6263 ndata[5] = 0;
6264 ndata[8] = 0;
6265 ndata[10] = 0;
6266 dma3_param.m_dma3_csectors = 0;
6267 dma3_param.m_dma3_msectors = 0;
6268 dma3_param.m_dma3_callback = 0;
6269 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
6270 return cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 5, &dma3_param, 1) >= 0;
6271 default:
6272 return cdvdman_send_ncmd(0x02, NULL, 0, 5, 0, 1) >= 0;
6273 }
6274}
6275
6276int sceCdStop(void)
6277{
6278 return cdvdman_send_ncmd(0x03, NULL, 0, 6, 0, 1) >= 0;
6279}
6280
6281int sceCdPause(void)
6282{
6283 return cdvdman_send_ncmd(0x04, NULL, 0, 7, 0, 1) >= 0;
6284}
6285
6286#ifdef DEAD_CODE
6287int cdvdman_ncmd_sender_0B(void)
6288{
6289 char ndata[1];
6290
6291 ndata[0] = 1;
6292 return cdvdman_send_ncmd(0x0B, ndata, sizeof(ndata), 0, 0, 1) >= 0;
6293}
6294#endif
6295
6296static unsigned int readtoc_timeout_alarm_cb(void *userdata)
6297{
6298 iop_sys_clock_t *sys_clock;
6299 USE_DEV5_MMIO_HWPORT();
6300
6301 sys_clock = (iop_sys_clock_t *)userdata;
6302 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
6303 dev5_mmio_hwport->m_dev5_reg_007 = 1;
6304 sys_clock->lo = 0;
6305 return 0;
6306}
6307
6308static int cdvdman_readtoc(u8 *toc, int param, int func)
6309{
6310 int last_err;
6311 cdvdman_dma3_parameter_t dma3_param;
6312 iop_sys_clock_t sysclk;
6313 char ndata[1];
6314
6315#ifdef CDVD_VARIANT_XOSD
6316 switch ( get_disk_type_ex() )
6317#else
6318 // The following call to sceCdGetDiskType was inlined
6319 switch ( sceCdGetDiskType() )
6320#endif
6321 {
6322 case SCECdPS2DVD:
6323 case SCECdDVDVR:
6324 case SCECdDVDV:
6325 dma3_param.m_cdvdreg_howto = 132;
6326 dma3_param.m_dma3_blkwords = 4;
6327 dma3_param.m_dma3_blkcount = 129;
6328 dma3_param.m_dma3_maddress = toc;
6329 dma3_param.m_dma3_msectors = 0;
6330 dma3_param.m_dma3_csectors = 0;
6331 dma3_param.m_dma3_callback = 0;
6332 ndata[0] = param;
6333 break;
6334 case SCECdPSCD:
6335 case SCECdPSCDDA:
6336 case SCECdPS2CD:
6337 case SCECdPS2CDDA:
6338 case SCECdCDDA:
6339 dma3_param.m_cdvdreg_howto = 128;
6340 dma3_param.m_dma3_blkwords = 32;
6341 dma3_param.m_dma3_blkcount = 8;
6342 dma3_param.m_dma3_maddress = toc;
6343 dma3_param.m_dma3_msectors = 0;
6344 dma3_param.m_dma3_csectors = 0;
6345 dma3_param.m_dma3_callback = 0;
6346 ndata[0] = 0;
6347 break;
6348 default:
6349 return 0;
6350 }
6351 if ( cdvdman_send_ncmd(0x09, ndata, sizeof(ndata), func, &dma3_param, 1) < 0 )
6352 {
6353 return 0;
6354 }
6355 sysclk.hi = 0;
6356 sysclk.lo = 0x15F90000;
6357 vSetAlarm(&sysclk, readtoc_timeout_alarm_cb, &sysclk);
6358 sceCdSync(3);
6359 vCancelAlarm(readtoc_timeout_alarm_cb, &sysclk);
6360 last_err = sceCdGetError();
6361 if ( g_cdvdman_minver_10700 && !sceCdPause() )
6362 {
6363 return 0;
6364 }
6365 sceCdSync(3);
6366 return last_err == SCECdErNO;
6367}
6368
6369static int cdvdman_gettoc(u8 *toc)
6370{
6371 // The following Kprintf was added for ioprp300x
6372 VERBOSE_KPRINTF(1, "sceCdReadToc() call 0x%p\n", toc);
6373 return cdvdman_readtoc(toc, 0, 3);
6374}
6375
6376#ifdef CDVD_VARIANT_OSD
6377int sceCdGetToc2(u8 *toc, int param)
6378{
6379 cdvdman_dma3_parameter_t dma3_param;
6380 char ndata[1];
6381
6382 dma3_param.m_cdvdreg_howto = 140;
6383 dma3_param.m_dma3_blkwords = 12;
6384 dma3_param.m_dma3_blkcount = 43;
6385 dma3_param.m_dma3_maddress = toc;
6386 dma3_param.m_dma3_msectors = 0;
6387 dma3_param.m_dma3_csectors = 0;
6388 dma3_param.m_dma3_callback = 0;
6389 ndata[0] = param;
6390 return cdvdman_send_ncmd(0x09, ndata, sizeof(ndata), 0, &dma3_param, 1) >= 0;
6391}
6392#endif
6393
6394u32 sceCdGetReadPos(void)
6395{
6396 int sector_sizes[4];
6397
6398 sector_sizes[0] = 0x800;
6399 sector_sizes[1] = 0x918;
6400 sector_sizes[2] = 0x924;
6401 if ( g_cdvdman_istruct.m_recover_status && g_cdvdman_istruct.m_recover_status != 3 )
6402 {
6403 return 0;
6404 }
6405 if ( g_cdvdman_cmdfunc == SCECdFuncReadCDDA || g_cdvdman_cmdfunc == 12 )
6406 {
6407 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
6408 }
6409 if ( g_cdvdman_istruct.m_read2_flag )
6410 {
6411 return g_cdvdman_readptr * sector_sizes[g_cdvdman_istruct.m_cdvdman_pattern];
6412 }
6413 if ( g_cdvdman_cmdfunc == SCECdFuncRead )
6414 {
6415 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
6416 }
6417 return 0;
6418}
6419
6420static int cdvdman_speedctl(u32 spindlctrl, int dvdflag, u32 maxlsn)
6421{
6422 u32 maxlsn_chk;
6423
6424 switch ( spindlctrl )
6425 {
6426 case SCECdSpinStm:
6427 return dvdflag ? 2 : 4;
6428 case SCECdSpinNom:
6429 if ( !dvdflag )
6430 {
6431 return 133;
6432 }
6433 if ( g_cdvdman_minver_10700 )
6434 {
6435 return 131;
6436 }
6437#ifdef CDVD_VARIANT_OSD
6438 // From DVD Player 3.11
6439 maxlsn_chk = 0x1C9000;
6440#else
6441 maxlsn_chk = 0x128000;
6442#endif
6443 if ( g_cdvdman_istruct.m_opo_or_para )
6444 {
6445 maxlsn -= (maxlsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn) ? g_cdvdman_istruct.m_layer_1_lsn : 0;
6446#ifdef CDVD_VARIANT_OSD
6447 // From DVD Player 3.11
6448 maxlsn_chk = 0x197000;
6449#else
6450 maxlsn_chk = 0x165000;
6451#endif
6452 }
6453 if ( maxlsn >= maxlsn_chk )
6454 {
6455 VERBOSE_KPRINTF(1, "Kprob Spd D lsn= %d\n", maxlsn);
6456 return 130;
6457 }
6458 return 133;
6459 case SCECdSpinX1:
6460 case 0xE:
6461 return 1;
6462 case SCECdSpinX2:
6463 return 2;
6464 case SCECdSpinX4:
6465 return dvdflag ? 2 : 131;
6466 case SCECdSpinX12:
6467 return dvdflag ? 3 : 4;
6468 case SCECdSpinNm2:
6469 return 64;
6470 case 0xC:
6471 return dvdflag ? 4 : 2;
6472 case 0xF:
6473 return 130;
6474 case 0x10:
6475 return dvdflag ? 130 : 131;
6476 case 0x11:
6477 return dvdflag ? 130 : 132;
6478 case 0x12:
6479 return dvdflag ? 1 : 131;
6480 case SCECdSpinMx:
6481 return dvdflag ? 3 : 5;
6482 default:
6483 return dvdflag ? 131 : 133;
6484 }
6485}
6486
6487static int cdvdman_isdvd(void)
6488{
6489 // The following call to sceCdGetDiskType was inlined
6490#ifdef CDVD_VARIANT_XOSD
6491 switch ( get_disk_type_ex() )
6492#else
6493 switch ( sceCdGetDiskType() )
6494#endif
6495 {
6496 case SCECdPSCD:
6497 case SCECdPSCDDA:
6498 case SCECdPS2CD:
6499 case SCECdPS2CDDA:
6500 case SCECdCDDA:
6501 g_cdvdman_istruct.m_tray_is_open = 1;
6502 return 0;
6503 case SCECdPS2DVD:
6504 case SCECdDVDVR:
6505 case SCECdDVDV:
6506 g_cdvdman_istruct.m_tray_is_open = 1;
6507 return 1;
6508 default:
6509 return 0;
6510 }
6511}
6512
6513static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func)
6514{
6515 cdvdman_dma3_parameter_t dma3_param;
6516 char ndata[11];
6517
6518 g_cdvdman_readbuf = buf;
6519 VERBOSE_KPRINTF(1, "sceCdRead0_Rty Lsn:%d nsec:%d dintrnsec %d func %08x\n", lsn, nsec, dintrsec, func);
6520 *(u32 *)ndata = lsn;
6521 *(u32 *)&ndata[4] = nsec;
6522 ndata[8] = mode->trycount;
6523 ndata[9] = cdvdman_speedctl(mode->spindlctrl, cdvdman_isdvd(), lsn + nsec);
6524 dma3_param.m_dma3_csectors = dintrsec;
6525 dma3_param.m_dma3_callback = (int (*)(void))func;
6526 dma3_param.m_dma3_msectors = nsec;
6527 dma3_param.m_dma3_maddress = buf;
6528 dma3_param.m_dma3_blkcount = (!(u16)dintrsec) ? nsec : 1;
6529 switch ( ncmd )
6530 {
6531 case 0x06:
6532 ndata[10] = mode->datapattern;
6533 switch ( mode->datapattern )
6534 {
6535 case SCECdSecS2328:
6536 dma3_param.m_dma3_blkwords = 6;
6537 dma3_param.m_dma3_blkcount *= 97;
6538 dma3_param.m_cdvdreg_howto = 134;
6539 break;
6540 case SCECdSecS2340:
6541 dma3_param.m_dma3_blkwords = 15;
6542 dma3_param.m_dma3_blkcount *= 39;
6543 dma3_param.m_cdvdreg_howto = 143;
6544 break;
6545 case SCECdSecS2048:
6546 default:
6547 dma3_param.m_dma3_blkwords = 32;
6548 dma3_param.m_dma3_blkcount *= 16;
6549 dma3_param.m_cdvdreg_howto = 128;
6550 break;
6551 }
6552 break;
6553 case 0x08:
6554 dma3_param.m_dma3_blkwords = 12;
6555 dma3_param.m_dma3_blkcount *= 43;
6556 dma3_param.m_cdvdreg_howto = 140;
6557 ndata[10] = 0;
6558 break;
6559 default:
6560 return 0;
6561 }
6562 return cdvdman_send_ncmd(ncmd, ndata, sizeof(ndata), ncmd == 0x06 ? 1 : 14, &dma3_param, 0) >= 0;
6563}
6564
6565int sceCdRead0(u32 lsn, u32 sectors, void *buffer, sceCdRMode *mode, int csec, void *callback)
6566{
6567 cdvdman_dma3_parameter_t dma3_param;
6568 char ndata[11];
6569 u32 efbits;
6570
6571 if ( PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6572 {
6573 return 0;
6574 }
6575 VERBOSE_KPRINTF(
6576 1,
6577 "DVD/CD sceCdRead0 sec %d num %d spin %d trycnt %d dptn %d adr %08x\n",
6578 lsn,
6579 sectors,
6580 mode->spindlctrl,
6581 mode->trycount,
6582 mode->datapattern,
6583 buffer);
6584 g_cdvdman_readbuf = buffer;
6585 dma3_param.m_dma3_csectors = (csec && (sectors < (u32)csec)) ? sectors : (u32)csec;
6586 dma3_param.m_dma3_callback = (int (*)(void))callback;
6587 dma3_param.m_dma3_msectors = sectors;
6588 dma3_param.m_dma3_blkcount = (!csec) ? sectors : 1;
6589 switch ( mode->datapattern )
6590 {
6591 case SCECdSecS2328:
6592 dma3_param.m_dma3_blkwords = 6;
6593 dma3_param.m_dma3_blkcount *= 97;
6594 dma3_param.m_cdvdreg_howto = 134;
6595 break;
6596 case SCECdSecS2340:
6597 dma3_param.m_dma3_blkwords = 15;
6598 dma3_param.m_dma3_blkcount *= 39;
6599 dma3_param.m_cdvdreg_howto = 143;
6600 break;
6601 case SCECdSecS2048:
6602 default:
6603 dma3_param.m_dma3_blkwords = 32;
6604 dma3_param.m_dma3_blkcount *= 16;
6605 dma3_param.m_cdvdreg_howto = 128;
6606 break;
6607 }
6608 // The following call to sceCdGetDiskType was inlined
6609#ifdef CDVD_VARIANT_OSD
6610 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
6611#else
6612 switch ( sceCdGetDiskType() )
6613 {
6614 case SCECdPSCD:
6615 case SCECdPSCDDA:
6616 case SCECdPS2CD:
6617 case SCECdPS2CDDA:
6618 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
6619 {
6620 vSetEventFlag(g_ncmd_evfid, 1);
6621 return 0;
6622 }
6623 g_cdvdman_istruct.m_dvd_flag = 0;
6624 break;
6625 case SCECdPS2DVD:
6626 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
6627 {
6628 vSetEventFlag(g_ncmd_evfid, 1);
6629 return 0;
6630 }
6631 g_cdvdman_istruct.m_dvd_flag = 1;
6632 break;
6633 default:
6634 vSetEventFlag(g_ncmd_evfid, 1);
6635 return 0;
6636 }
6637#endif
6638 g_cdvdman_istruct.m_read_mode = *mode;
6639 g_cdvdman_istruct.m_read_callback = callback;
6640 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
6641 g_cdvdman_istruct.m_read_lsn = lsn;
6642 g_cdvdman_istruct.m_read_sectors = sectors;
6643 *(u32 *)ndata = lsn;
6644 *(u32 *)&ndata[4] = sectors;
6645 ndata[8] = mode->trycount;
6646 ndata[9] = cdvdman_speedctl(mode->spindlctrl, g_cdvdman_istruct.m_dvd_flag, lsn + sectors);
6647 g_cdvdman_istruct.m_read_buf = buffer;
6648 ndata[10] = mode->datapattern;
6649 dma3_param.m_dma3_maddress = buffer;
6650 VERBOSE_KPRINTF(1, "Read Command call\n");
6651 if ( cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 1, &dma3_param, 0) < 0 )
6652 {
6653 vSetEventFlag(g_ncmd_evfid, 1);
6654 return 0;
6655 }
6656 vSetEventFlag(g_ncmd_evfid, 1);
6657 return 1;
6658}
6659
6660static int read_cdvd_cb(cdvdman_internal_struct_t *common)
6661{
6662 int sblock;
6663 int i;
6664 u32 cdreadlsn;
6665 int syncdec_res_1;
6666 sceCdlLOCCD cdrloc;
6667
6668 sblock = 0;
6669 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
6670 {
6671 char syncdec_res_4;
6672 int errlsn;
6673
6674 syncdec_res_4 = 0;
6675 if ( common->m_read2_flag == 3 )
6676 {
6677 sblock = 0x924;
6678 cdrloc.minute = cdvdman_syncdec(
6679 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
6680 cdrloc.second = cdvdman_syncdec(
6681 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1]);
6682 cdrloc.sector = cdvdman_syncdec(
6683 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2]);
6684 cdreadlsn = sceCdPosToInt(&cdrloc);
6685 }
6686 else
6687 {
6688 sblock = 0x810;
6689 syncdec_res_1 = (u8)cdvdman_syncdec(
6690 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 3]);
6691 syncdec_res_1 +=
6692 (u8)cdvdman_syncdec(
6693 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2])
6694 << 8;
6695 syncdec_res_1 +=
6696 (u8)cdvdman_syncdec(
6697 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1])
6698 << 16;
6699 syncdec_res_4 = cdvdman_syncdec(
6700 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
6701 if ( !common->m_cdvdman_dma3sec && !common->m_interupt_read_state )
6702 {
6703 common->m_interupt_read_state = (syncdec_res_4 & 0xC) | (((syncdec_res_4 & 0xC) && i) ? 0x80 : 0);
6704 }
6705 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);
6706 }
6707 errlsn = common->m_cdvdman_lsn + common->m_cdvdman_csec + common->m_cdvdman_dma3sec + i;
6708 if ( cdreadlsn != (u32)errlsn )
6709 {
6710 VERBOSE_KPRINTF(
6711 1, "Read_IOP Sector_ID error lsn= %d readlsn= %d layer= %d\n", errlsn, cdreadlsn, (syncdec_res_4 & 1));
6712 break;
6713 }
6714 }
6715 if ( i == common->m_dma3_param.m_dma3_csectors )
6716 {
6717 unsigned int size;
6718
6719 size = 0;
6720 switch ( common->m_cdvdman_pattern )
6721 {
6722 case 0:
6723 size = 0x800;
6724 break;
6725 case 1:
6726 default:
6727 size = 0x918;
6728 break;
6729 case 2:
6730 optimized_memcpy(
6731 &((char *)(common->m_cdvdman_rbuffer))[0x924 * common->m_cdvdman_dma3sec],
6732 (const char *)g_cdvdman_ptoc,
6733 0x924 * i);
6734 break;
6735 }
6736 if ( size )
6737 {
6738 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
6739 {
6740 optimized_memcpy(
6741 &((char *)(common->m_cdvdman_rbuffer))[(common->m_cdvdman_dma3sec + i) * size],
6742 (const char *)&g_cdvdman_ptoc[12 + (i * sblock)],
6743 size);
6744 }
6745 }
6746 g_cdvdman_readptr = common->m_cdvdman_csec + common->m_cdvdman_dma3sec;
6747 }
6748 else
6749 {
6750 common->m_sync_error += 1;
6751 }
6752 return 1;
6753}
6754
6755static int cdvdman_read(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int decflag, int shift, int ef1, int ef2)
6756{
6757 int read_res;
6758 int state;
6759 int scres_unused;
6760 int dvd;
6761 int ready;
6762
6763 dvd = cdvdman_isdvd();
6764 if ( dvd )
6765 {
6766 if ( !DvdDual_infochk() )
6767 {
6768 if ( ef1 )
6769 {
6770 vSetEventFlag(ef1, ef2);
6771 }
6772 return 0;
6773 }
6774 lsn = sceCdLsnDualChg(lsn);
6775 }
6776 else if ( mode->datapattern == SCECdSecS2328 || (g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state) )
6777 {
6778 int read0_res;
6779
6780 if ( g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state && mode->spindlctrl == SCECdSpinNom )
6781 {
6782 mode->spindlctrl = SCECdSpinStm;
6783 }
6784 CpuSuspendIntr(&state);
6785 read0_res = sceCdRead0(lsn, sectors, buf, mode, 0, 0);
6786 if ( ef1 )
6787 {
6788 vSetEventFlag(ef1, ef2);
6789 }
6790 CpuResumeIntr(state);
6791 return read0_res;
6792 }
6793 CpuSuspendIntr(&state);
6794 ready = sceCdDiskReady(8) & 0xC0;
6795 if ( ready != 0x40 || g_cdvdman_istruct.m_read2_flag )
6796 {
6797 // The following Kprintf was modified for ioprp300x
6798 VERBOSE_KPRINTF(
6799 1,
6800 "sceCdRead: Double Booking error r2f= %d waf= %d rdy= %02x\n",
6801 g_cdvdman_istruct.m_read2_flag,
6802 g_cdvdman_istruct.m_wait_flag,
6803 ready);
6804 if ( ef1 )
6805 {
6806 vSetEventFlag(ef1, ef2);
6807 }
6808 CpuResumeIntr(state);
6809 return 0;
6810 }
6811 if ( decflag )
6812 {
6813 g_cdvdman_istruct.m_dec_shift = shift;
6814 g_cdvdman_istruct.m_dec_state = 1;
6815 }
6816 g_cdvdman_readbuf = buf;
6817 g_cdvdman_readptr = 0;
6818 g_cdvdman_istruct.m_cdvdman_lsn = lsn;
6819 g_cdvdman_istruct.m_cdvdman_csec = 0;
6820 g_cdvdman_istruct.m_cdvdman_nsec = sectors;
6821 g_cdvdman_istruct.m_cdvdman_rbuffer = (int)buf;
6822 g_cdvdman_istruct.m_cdvdman_pattern = dvd ? SCECdSecS2048 : mode->datapattern;
6823 g_cdvdman_istruct.m_cdvdman_cdrmode.trycount = mode->trycount;
6824 g_cdvdman_istruct.m_cdvdman_cdrmode.spindlctrl = mode->spindlctrl;
6825 g_cdvdman_istruct.m_cdvdman_cdrmode.datapattern = dvd ? SCECdSecS2048 : SCECdSecS2340;
6826 g_cdvdman_istruct.m_read2_flag = dvd ? 1 : 3;
6827 g_cdvdman_istruct.m_sync_error = 0;
6828 g_cdvdman_istruct.m_interupt_read_state = 0;
6829 g_cdvdman_istruct.m_cdvdman_rsec = (sectors >= 0x41) ? (((lsn & 0xF)) ? (0x10 - (lsn & 0xF)) : 0x40) : sectors;
6830 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6831 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6832 vSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6833 read_res = (dvd ? sceCdRV : sceCdRead0)(
6834 lsn,
6835 g_cdvdman_istruct.m_cdvdman_rsec,
6836 g_cdvdman_ptoc,
6837 dvd ? mode : &g_cdvdman_istruct.m_cdvdman_cdrmode,
6838 g_cdvdman_cache_sector_count,
6839 read_cdvd_cb);
6840 if ( !read_res )
6841 {
6842 g_cdvdman_istruct.m_last_error = SCECdErREADCFR;
6843 g_cdvdman_istruct.m_cdvdman_rsec = 0;
6844 g_cdvdman_istruct.m_read2_flag = 0;
6845 if ( g_cdvdman_istruct.m_dec_state )
6846 {
6847 g_cdvdman_istruct.m_dec_shift = 0;
6848 g_cdvdman_istruct.m_check_version = 0;
6849 g_cdvdman_istruct.m_dec_state = 0;
6850 sceCdDecSet(0, 0, 0);
6851 }
6852 vCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6853 }
6854 if ( ef1 )
6855 {
6856 vSetEventFlag(ef1, ef2);
6857 }
6858 CpuResumeIntr(state);
6859 return !!read_res;
6860}
6861
6862int sceCdRE(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
6863{
6864 return cdvdman_read(lsn, sectors, buf, mode, 0, 0, 0, 0);
6865}
6866
6867int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
6868{
6869 iop_event_info_t efinfo;
6870 int state;
6871
6872 // Unofficial: initialize to 0
6873 memset(&efinfo, 0, sizeof(efinfo));
6874 CpuSuspendIntr(&state);
6875 vReferEventFlagStatus(g_fio_fsv_evfid, &efinfo);
6876 if ( !(efinfo.currBits & 1) )
6877 {
6878 CpuResumeIntr(state);
6879 return 0;
6880 }
6881 vClearEventFlag(g_fio_fsv_evfid, ~1);
6882 CpuResumeIntr(state);
6883 return cdvdman_read(lbn, sectors, buffer, mode, 0, 0, g_fio_fsv_evfid, 1);
6884}
6885
6886static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data)
6887{
6888 return decflag ? ((u8)(((u8)data << (shift % 8)) | ((u8)data >> (8 - shift % 8))) ^ (u8)decxor) : (u8)data;
6889}
6890
6891static void Read2intrCDVD(int read2_flag)
6892{
6893 iCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6894 if ( g_cdvdman_istruct.m_last_error != SCECdErNO || g_cdvdman_retries >= 5 )
6895 {
6896 if ( g_cdvdman_istruct.m_last_error == SCECdErNO )
6897 {
6898 g_cdvdman_istruct.m_last_error = SCECdErREADCF;
6899 }
6900 g_cdvdman_istruct.m_read2_flag = 0;
6901 g_cdvdman_retries = 0;
6902 g_cdvdman_rtindex = 0;
6903 g_cdvdman_readptr = 0;
6904 if ( g_cdvdman_istruct.m_dec_state )
6905 {
6906 g_cdvdman_istruct.m_dec_shift = 0;
6907 g_cdvdman_istruct.m_check_version = 0;
6908 g_cdvdman_istruct.m_dec_state = 0;
6909 }
6910 g_cdvdman_istruct.m_interupt_read_state = 0;
6911 }
6912 else if ( !g_cdvdman_istruct.m_interupt_read_state || g_cdvdman_istruct.m_cdvdman_csec )
6913 {
6914 int scres_unused;
6915
6916 g_cdvdman_istruct.m_interupt_read_state = 0;
6917 if ( g_cdvdman_istruct.m_sync_error )
6918 {
6919 u32 lsn_tmp;
6920
6921 if ( !g_cdvdman_rtindex )
6922 {
6923 g_cdvdman_rtindex = 3;
6924 g_cdvdman_retries += 1;
6925 }
6926 g_cdvdman_istruct.m_sync_error = 0;
6927 lsn_tmp = g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec;
6928 if ( lsn_tmp >= 0x30 )
6929 {
6930 lsn_tmp -= 0x10 * (g_cdvdman_rtindex - 1);
6931 }
6932 else
6933 {
6934 lsn_tmp += 0x10 * (g_cdvdman_rtindex - 1);
6935 }
6936 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
6937 lsn_tmp,
6938 g_cdvdman_istruct.m_cdvdman_rsec,
6939 g_cdvdman_ptoc,
6940 &g_cdvdman_istruct.m_cdvdman_cdrmode,
6941 g_cdvdman_cache_sector_count,
6942 read_cdvd_cb) )
6943 {
6944 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6945 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6946 iSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6947 }
6948 else
6949 {
6950 VERBOSE_KPRINTF(1, "Retry Read Fatal Error\n");
6951 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
6952 g_cdvdman_istruct.m_read2_flag = 0;
6953 g_cdvdman_retries = 0;
6954 g_cdvdman_rtindex = 0;
6955 g_cdvdman_readptr = 0;
6956 if ( g_cdvdman_istruct.m_dec_state )
6957 {
6958 g_cdvdman_istruct.m_dec_shift = 0;
6959 g_cdvdman_istruct.m_check_version = 0;
6960 g_cdvdman_istruct.m_dec_state = 0;
6961 }
6962 }
6963 g_cdvdman_rtindex -= !!g_cdvdman_rtindex;
6964 }
6965 else
6966 {
6967 int cdsectorsz;
6968
6969 g_cdvdman_retries = 0;
6970 switch ( g_cdvdman_istruct.m_cdvdman_pattern )
6971 {
6972 case 0:
6973 cdsectorsz = 0x800;
6974 break;
6975 case 1:
6976 default:
6977 cdsectorsz = 0x918;
6978 break;
6979 case 2:
6980 cdsectorsz = 0x924;
6981 break;
6982 }
6983 g_cdvdman_istruct.m_cdvdman_rbuffer += cdsectorsz * g_cdvdman_istruct.m_cdvdman_rsec;
6984 g_cdvdman_istruct.m_cdvdman_csec += g_cdvdman_istruct.m_cdvdman_rsec;
6985 if ( (unsigned int)g_cdvdman_istruct.m_cdvdman_csec < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec )
6986 {
6987 g_cdvdman_istruct.m_cdvdman_rsec =
6988 ((unsigned int)(g_cdvdman_istruct.m_cdvdman_csec + 0x40) < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec) ?
6989 0x40 :
6990 (g_cdvdman_istruct.m_cdvdman_nsec - g_cdvdman_istruct.m_cdvdman_csec);
6991 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
6992 g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec,
6993 g_cdvdman_istruct.m_cdvdman_rsec,
6994 g_cdvdman_ptoc,
6995 &g_cdvdman_istruct.m_cdvdman_cdrmode,
6996 g_cdvdman_cache_sector_count,
6997 read_cdvd_cb) )
6998 {
6999 g_cdvdman_read_alarm_cb_timeout.hi = 0;
7000 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
7001 iSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
7002 }
7003 else
7004 {
7005 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
7006 g_cdvdman_istruct.m_read2_flag = 0;
7007 g_cdvdman_readptr = 0;
7008 if ( g_cdvdman_istruct.m_dec_state )
7009 {
7010 g_cdvdman_istruct.m_dec_shift = 0;
7011 g_cdvdman_istruct.m_check_version = 0;
7012 g_cdvdman_istruct.m_dec_state = 0;
7013 }
7014 }
7015 }
7016 else
7017 {
7018 g_cdvdman_istruct.m_read2_flag = 0;
7019 g_cdvdman_readptr = 0;
7020 if ( g_cdvdman_istruct.m_dec_state )
7021 {
7022 g_cdvdman_istruct.m_dec_shift = 0;
7023 g_cdvdman_istruct.m_check_version = 0;
7024 g_cdvdman_istruct.m_dec_state = 0;
7025 }
7026 }
7027 }
7028 }
7029 else
7030 {
7031 g_cdvdman_istruct.m_last_error = ((g_cdvdman_istruct.m_interupt_read_state & 0x80)) ? SCECdErREADCF : SCECdErIPI;
7032 g_cdvdman_istruct.m_interupt_read_state = 0;
7033 VERBOSE_KPRINTF(1, "IPIerr emu Hit Dummy Err %02x\n", (u8)g_cdvdman_istruct.m_last_error);
7034 g_cdvdman_istruct.m_read2_flag = 0;
7035 g_cdvdman_retries = 0;
7036 g_cdvdman_rtindex = 0;
7037 g_cdvdman_readptr = 0;
7038 if ( g_cdvdman_istruct.m_dec_state )
7039 {
7040 g_cdvdman_istruct.m_dec_shift = 0;
7041 g_cdvdman_istruct.m_check_version = 0;
7042 g_cdvdman_istruct.m_dec_state = 0;
7043 }
7044 }
7045}
7046
7048{
7049 (void)tag;
7050 (void)mode;
7051
7052 return 0;
7053}
7054
7055static int cdvdman_readfull(u32 lsn, u32 sectors, void *buf, const sceCdRMode *mode, int flag)
7056{
7057 cdvdman_dma3_parameter_t dma3_param;
7058 char ndata[11];
7059
7060 VERBOSE_KPRINTF(1, "lsn:%d nsec:%d buf:% cmdmode:%d\n", lsn, sectors, buf, flag);
7061 // The following Kprintf was added for ioprp300x
7062 VERBOSE_KPRINTF(1, "DA Read lsn= %d nsec= %d datapattern= %d\n", lsn, sectors, mode->datapattern);
7063 g_cdvdman_readbuf = buf;
7064#ifdef CDVD_VARIANT_XOSD
7065 dma3_param.m_dma3_csectors = sectors;
7066 dma3_param.m_dma3_msectors = (u16)sectors;
7067#else
7068 dma3_param.m_dma3_csectors = 0;
7069 dma3_param.m_dma3_msectors = 0;
7070#endif
7071 dma3_param.m_dma3_callback = 0;
7072 dma3_param.m_dma3_blkcount = sectors;
7073 switch ( mode->datapattern )
7074 {
7075 case SCECdSecS2328:
7076 dma3_param.m_dma3_blkwords = 8;
7077 dma3_param.m_dma3_blkcount *= 74;
7078 dma3_param.m_cdvdreg_howto = 136;
7079 break;
7080 case SCECdSecS2340:
7081 dma3_param.m_dma3_blkwords = 12;
7082 dma3_param.m_dma3_blkcount *= 51;
7083 dma3_param.m_cdvdreg_howto = 140;
7084 break;
7085 case SCECdSecS2048:
7086 default:
7087 dma3_param.m_dma3_blkwords = 12;
7088 dma3_param.m_dma3_blkcount *= 49;
7089 dma3_param.m_cdvdreg_howto = 140;
7090 break;
7091 }
7092 // The following call to sceCdGetDiskType() was inlined
7093#ifdef CDVD_VARIANT_XOSD
7094 switch ( get_disk_type_ex() )
7095#else
7096 switch ( sceCdGetDiskType() )
7097#endif
7098 {
7099 case SCECdPSCDDA:
7100 case SCECdPS2CDDA:
7101 case SCECdCDDA:
7102 break;
7103 default:
7104 return 0;
7105 }
7106#ifndef CDVD_VARIANT_OSD
7107 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
7108 {
7109 return 0;
7110 }
7111#endif
7112 *(u32 *)ndata = lsn;
7113 *(u32 *)&ndata[4] = sectors;
7114 ndata[8] = mode->trycount;
7115 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 0, lsn + sectors);
7116 dma3_param.m_dma3_maddress = buf;
7117 ndata[10] = mode->datapattern;
7118 return cdvdman_send_ncmd((!flag) ? 0x07 : 0x0E, ndata, sizeof(ndata), (!flag) ? 2 : 12, &dma3_param, 1) >= 0;
7119}
7120
7121// cppcheck-suppress constParameterPointer
7122int sceCdReadCDDA(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
7123{
7124 return cdvdman_readfull(lbn, sectors, buffer, mode, 0);
7125}
7126
7127#ifdef CDVD_VARIANT_OSD
7128// cppcheck-suppress constParameterPointer
7129int sceCdReadFull(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
7130{
7131 return g_cdvdman_minver_20800 ? cdvdman_readfull(lsn, sectors, buf, mode, 1) :
7132 cdvdman_readfull(lsn, sectors, buf, mode, 0);
7133}
7134#endif
7135
7136int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
7137{
7138 cdvdman_dma3_parameter_t dma3_param;
7139 char ndata[11];
7140 u32 efbits;
7141
7142 if (
7143#ifdef CDVD_VARIANT_XOSD
7144 get_disk_type_ex() != SCECdPS2DVD
7145#else
7146 // The following call to sceCdGetDiskType was inlined
7148#endif
7149#ifndef CDVD_VARIANT_OSD
7150 || (g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF)
7151#endif
7152 || (PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND) )
7153 {
7154 return 0;
7155 }
7156 VERBOSE_KPRINTF(
7157 1, "RV read: sec %d num %d spin %d trycnt %d addr %08x\n", lsn, sectors, mode->spindlctrl, mode->trycount, buf);
7158 g_cdvdman_readbuf = buf;
7159 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
7160 g_cdvdman_istruct.m_read_mode = *mode;
7161 g_cdvdman_istruct.m_read_lsn = lsn;
7162 g_cdvdman_istruct.m_read_sectors = sectors;
7163 *(u32 *)ndata = lsn;
7164 *(u32 *)&ndata[4] = sectors;
7165 ndata[8] = mode->trycount;
7166 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 1, lsn + sectors);
7167 ndata[10] = 0;
7168 dma3_param.m_dma3_csectors = (arg5 && (sectors < (u32)arg5)) ? sectors : (u32)arg5;
7169 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
7170 dma3_param.m_cdvdreg_howto = 140;
7171 dma3_param.m_dma3_blkwords = 12;
7172 g_cdvdman_istruct.m_read_buf = buf;
7173 dma3_param.m_dma3_blkcount = (!arg5) ? sectors : 1;
7174 dma3_param.m_dma3_blkcount *= 43;
7175 dma3_param.m_dma3_msectors = sectors;
7176 dma3_param.m_dma3_callback = (int (*)(void))cb;
7177 g_cdvdman_istruct.m_read_callback = cb;
7178 dma3_param.m_dma3_maddress = buf;
7179 if ( cdvdman_send_ncmd(0x08, ndata, sizeof(ndata), 14, &dma3_param, 0) < 0 )
7180 {
7181 vSetEventFlag(g_ncmd_evfid, 1);
7182 return 0;
7183 }
7184 vSetEventFlag(g_ncmd_evfid, 1);
7185 return 1;
7186}
7187
7188#ifdef CDVD_VARIANT_OSD
7189// cppcheck-suppress constParameterPointer
7190int sceCdReadDVDV(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
7191{
7192 cdvdman_dma3_parameter_t dma3_param;
7193 char ndata[11];
7194
7195#ifdef CDVD_VARIANT_XOSD
7196 switch ( get_disk_type_ex() )
7197#else
7198 // The following call to sceCdGetDiskType was inlined
7199 switch ( sceCdGetDiskType() )
7200#endif
7201 {
7202 case SCECdPS2DVD:
7203 case SCECdDVDVR:
7204 case SCECdDVDV:
7205 break;
7206 default:
7207 return 0;
7208 }
7209 switch ( mode->spindlctrl )
7210 {
7211 case SCECdSpinMax:
7212 case SCECdSpinX4:
7213 ndata[9] = 3;
7214 break;
7215 case SCECdSpinX1:
7216 ndata[9] = 1;
7217 break;
7218 case SCECdSpinX2:
7219 case 0xC:
7220 ndata[9] = 4;
7221 break;
7222 case 0xA:
7223 ndata[9] = 0x40;
7224 break;
7225 case 0xB:
7226 ndata[9] = 2;
7227 break;
7228 default:
7229 ndata[9] = 0x83;
7230 break;
7231 }
7232 *(u32 *)ndata = lbn;
7233 *(u32 *)&ndata[4] = sectors;
7234 dma3_param.m_cdvdreg_howto = 140;
7235 dma3_param.m_dma3_blkwords = 12;
7236 dma3_param.m_dma3_blkcount = 43 * sectors;
7237 ndata[10] = 0;
7238 dma3_param.m_dma3_maddress = buffer;
7239 dma3_param.m_dma3_msectors = 0;
7240 dma3_param.m_dma3_csectors = 0;
7241 dma3_param.m_dma3_callback = 0;
7242 ndata[8] = mode->trycount;
7243 return cdvdman_send_ncmd(0x08, ndata, sizeof(ndata), 9, &dma3_param, 1) >= 0;
7244}
7245#endif
7246
7247int sceCdSeek(u32 lbn)
7248{
7249 char ndata[4];
7250
7251 *(u32 *)ndata = lbn;
7252 if ( cdvdman_isdvd() )
7253 {
7254 if ( !DvdDual_infochk() )
7255 {
7256 return 0;
7257 }
7258 *(u32 *)ndata = sceCdLsnDualChg(lbn);
7259 }
7260 return cdvdman_send_ncmd(0x05, ndata, sizeof(ndata), 4, 0, 1) >= 0;
7261}
7262
7263#ifdef CDVD_VARIANT_XOSD
7264static unsigned int sceCdChgSpdlCtrl(int mode)
7265{
7266 unsigned int retval;
7267 char ndata[1];
7268
7269 ndata[0] = mode;
7270 retval = ~cdvdman_send_ncmd(0x0F, ndata, sizeof(ndata), 0xF, 0, 0);
7271 VERBOSE_KPRINTF(1, "Called sceCdChgSpdlCtrl mode:%d ret= %d\n", mode & 0xFF, retval >> 31);
7272 return retval >> 31;
7273}
7274#endif
7275
7276// cppcheck-suppress funcArgNamesDifferent
7277int sceCdRI(u8 *buffer, u32 *status)
7278{
7279 int retval;
7280 char rdata[9];
7281
7282 retval = set_prev_command(0x12, NULL, 0, rdata, sizeof(rdata), 1);
7283 *status = rdata[0];
7284 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7285 return retval;
7286}
7287
7288int sceCdRM(char *buffer, u32 *status)
7289{
7290 int retval;
7291 int cmd_tmp2;
7292 char rdata[9];
7293 char wdata[1];
7294 u32 efbits;
7295
7296 *status = SCECdErNO;
7297 if ( sceCdMV((u8 *)rdata, status) != 1 || (unsigned int)(rdata[3] | (rdata[2] << 8) | (rdata[1] << 16)) < 0x10500 )
7298 {
7299 strcpy(buffer, "M_NAME_UNKNOWN");
7300 buffer[15] = 0;
7301 *status |= 0x40;
7302 return 1;
7303 }
7304 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
7305 {
7306 return 0;
7307 }
7308 DelayThread(2000);
7309 wdata[0] = 0;
7310 retval = set_prev_command(0x17, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
7311 *status = rdata[0];
7312 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7313 DelayThread(2000);
7314 wdata[0] = 8;
7315 cmd_tmp2 = set_prev_command(0x17, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
7316 *status |= rdata[0];
7317 memcpy(&buffer[8], &rdata[1], sizeof(rdata) - 1);
7318 vSetEventFlag(g_scmd_evfid, 1);
7319 return retval ? (!!cmd_tmp2) : 0;
7320}
7321
7322#ifdef CDVD_VARIANT_OSD
7323// Not implemented XOSD or DVD Player 3.11
7324// cppcheck-suppress funcArgNamesDifferent
7325int sceCdWI(const u8 *buffer, u32 *status)
7326{
7327 int retres;
7328
7329 DelayThread(16000);
7330 *status = SCECdErNO;
7331 retres = set_prev_command(0x13, (const char *)buffer, 8, (char *)status, 1, 1);
7332 DelayThread(16000);
7333 return retres;
7334}
7335
7336// Not implemented XOSD or DVD Player 3.11
7337int sceCdWM(const char *buffer, u32 *status)
7338{
7339 int retres;
7340 char rdata[1];
7341 char wdata[9];
7342
7343 *status = SCECdErNO;
7344 if ( sceCdMV((u8 *)wdata, status) != 1 || (unsigned int)(wdata[3] | (wdata[2] << 8) | (wdata[1] << 16)) < 0x10500 )
7345 {
7346 *status |= 0x40;
7347 return 1;
7348 }
7349 DelayThread(2000);
7350 wdata[0] = 0;
7351 // The following was inlined
7352 memcpy(&wdata[1], &buffer[0], sizeof(wdata) - 1);
7353 retres = set_prev_command(0x18, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7354 *status = rdata[0];
7355 DelayThread(16000);
7356 wdata[0] = 8;
7357 // The following was inlined
7358 memcpy(&wdata[1], &buffer[8], sizeof(wdata) - 1);
7359 retres = set_prev_command(0x18, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && retres;
7360 *status |= rdata[0];
7361 DelayThread(16000);
7362 return !!retres;
7363}
7364
7365// cppcheck-suppress funcArgNamesDifferent
7366int sceCdReadConsoleID(u8 *buffer, u32 *status)
7367{
7368 int retval;
7369 char rdata[9];
7370 char wdata[1];
7371
7372 wdata[0] = 0x45;
7373 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7374 *status = rdata[0];
7375 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7376 return retval;
7377}
7378
7379// Not implemented XOSD or DVD Player 3.11
7380int sceCdWriteConsoleID(const u8 *buffer, u32 *status)
7381{
7382 int retval;
7383 char wdata[9];
7384
7385 DelayThread(16000);
7386 *status = SCECdErNO;
7387 wdata[0] = 0x44;
7388 memcpy(&wdata[1], buffer, 8);
7389 retval = set_prev_command(0x03, wdata, sizeof(wdata), (char *)status, 1, 1);
7390 DelayThread(16000);
7391 return retval;
7392}
7393#endif
7394
7395int sceCdMV(u8 *buffer, u32 *status)
7396{
7397 int retval;
7398 char rdata[4];
7399 char wdata[1];
7400
7401 wdata[0] = 0x00;
7402 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7403#ifdef CDVD_VARIANT_XOSD
7404 *status = SCECdErNO;
7405#else
7406 *status = rdata[0] & 0x80;
7407#endif
7408 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]);
7409#ifndef CDVD_VARIANT_XOSD
7410 rdata[0] &= ~0x80;
7411#endif
7412 memcpy(buffer, rdata, sizeof(rdata));
7413 return retval;
7414}
7415
7416#ifdef CDVD_VARIANT_XOSD
7417static int cdvdman_get_renewal_date(u8 *buffer, u32 *status)
7418{
7419 int retval;
7420 char rdata[6];
7421 char wdata[1];
7422
7423 *status = SCECdErNO;
7424 wdata[0] = 0xFD;
7425 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7426 if ( retval )
7427 {
7428 *status = (u8)rdata[0];
7429 }
7430 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7431 return retval;
7432}
7433#endif
7434
7435#ifndef CDVD_VARIANT_XOSD
7436static int cdvdman_scmd_sender_03_30(u8 *buf, u32 *status)
7437{
7438 int retval;
7439 char rdata[2];
7440 char wdata[2];
7441
7442 if ( g_cdvdman_minver_50000 )
7443 {
7444 return 0;
7445 }
7446 wdata[0] = 0x30;
7447 wdata[1] = 2;
7448 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7449 *status = (u8)rdata[0];
7450 *buf = rdata[1];
7451 return retval;
7452}
7453#endif
7454
7455#ifdef CDVD_VARIANT_OSD
7456int sceCdReadSUBQ(void *buffer, u32 *status)
7457{
7458 int retval;
7459 int i;
7460 int dev5_reg_00E;
7461 int dev5_reg_00D;
7462 int dev5_reg_00C;
7463 char rdata[11];
7464 u32 efbits;
7465 USE_DEV5_MMIO_HWPORT();
7466
7467 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
7468 {
7469 return 0;
7470 }
7471 dev5_mmio_hwport->m_dev5_reg_009 = 0;
7472 retval = cdvdman_send_scmd2(0x02, NULL, 0, rdata, sizeof(rdata), 0);
7473 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7474 for ( i = 0; i < 10; i += 1 )
7475 {
7476 int tmp00E;
7477 int tmp00D;
7478 int tmp00C;
7479
7480 dev5_reg_00E = dev5_mmio_hwport->m_dev5_reg_00E;
7481 dev5_reg_00D = dev5_mmio_hwport->m_dev5_reg_00D;
7482 dev5_reg_00C = dev5_mmio_hwport->m_dev5_reg_00C;
7483 tmp00E = dev5_mmio_hwport->m_dev5_reg_00E;
7484 tmp00D = dev5_mmio_hwport->m_dev5_reg_00D;
7485 tmp00C = dev5_mmio_hwport->m_dev5_reg_00C;
7486 if ( dev5_reg_00E == tmp00E && dev5_reg_00D == tmp00D && dev5_reg_00C == tmp00C )
7487 {
7488 break;
7489 }
7490 }
7491 if ( i != 10 )
7492 {
7493 *((u8 *)buffer + 9) = dev5_reg_00E;
7494 *((u8 *)buffer + 8) = dev5_reg_00D;
7495 *((u8 *)buffer + 7) = dev5_reg_00C;
7496 }
7497 *status = rdata[0];
7498 vSetEventFlag(g_scmd_evfid, 1);
7499 return retval;
7500}
7501
7502// cppcheck-suppress funcArgNamesDifferent
7503int sceCdForbidDVDP(u32 *status)
7504{
7505 int retval;
7506 char rdata[1];
7507
7508 // Unofficial: NULL for wdata if length is 0
7509 retval = set_prev_command(0x15, NULL, 0, rdata, sizeof(rdata), 1);
7510 *status = (u8)rdata[0];
7511 return retval;
7512}
7513#endif
7514
7515int sceCdMmode(int media)
7516{
7517 g_cdvdman_mmode = media;
7518 return 1;
7519}
7520
7521#ifdef CDVD_VARIANT_OSD
7522// cppcheck-suppress funcArgNamesDifferent
7523int sceCdForbidRead(u32 *status)
7524{
7525 *status = SCECdErNO;
7526 // Unofficial: NULL for wdata if length is 0
7527 return set_prev_command(0x19, NULL, 0, (char *)status, 1, 1);
7528}
7529
7530int sceCdBootCertify(const u8 *romname)
7531{
7532 char rdata[1];
7533
7534 VERBOSE_KPRINTF(1, "BC %d %d %d %d\n", *romname, romname[1], romname[2], romname[3]);
7535 return set_prev_command(0x1A, (const char *)romname, 4, rdata, sizeof(rdata), 1);
7536}
7537#endif
7538
7539// cppcheck-suppress funcArgNamesDifferent
7540int sceCdCancelPOffRdy(u32 *status)
7541{
7542 *status = SCECdErNO;
7543 // Unofficial: NULL for wdata if length is 0
7544 return g_cdvdman_minver_20400 ? set_prev_command(0x1B, NULL, 0, (char *)status, 1, 1) : 1;
7545}
7546
7547#ifdef CDVD_VARIANT_OSD
7548// cppcheck-suppress funcArgNamesDifferent
7549int sceCdBlueLEDCtl(u8 control, u32 *status)
7550{
7551 char wdata[1];
7552
7553 *status = SCECdErNO;
7554 wdata[0] = control;
7555 return set_prev_command(0x1C, wdata, sizeof(wdata), (char *)status, 1, 1);
7556}
7557#endif
7558
7559static unsigned int power_off_alarm_cb(void *userdata)
7560{
7562
7563 s = (cdvdman_internal_struct_t *)userdata;
7564 s->m_power_flag = 0;
7565 return 0;
7566}
7567
7568// cppcheck-suppress funcArgNamesDifferent
7569int sceCdPowerOff(u32 *status)
7570{
7571 int retval;
7572
7573 *status = SCECdErNO;
7574 VERBOSE_KPRINTF(1, "sceCdPowerOff Call\n");
7575#ifndef CDVD_VARIANT_XOSD
7576 if ( !g_cdvdman_minver_x_model_15 )
7577 {
7578 while ( (sceCdStatus() & SCECdStatShellOpen) )
7579 {
7580 u32 traychk;
7581
7582 sceCdTrayReq(SCECdTrayClose, &traychk);
7583 vDelayThread(250000);
7584 }
7585 }
7586#endif
7587 retval = set_prev_command(0x0F, NULL, 0, (char *)status, 1, 1);
7588 if ( !retval )
7589 {
7590 g_cdvdman_istruct.m_power_flag = 0;
7591 return 0;
7592 }
7593 KPRINTF("PowerOff Start...\n");
7594 g_cdvdman_istruct.m_power_flag = 1;
7595 g_cdvdman_power_off_timeout.hi = 0;
7596 g_cdvdman_power_off_timeout.lo = 0xAFC8000;
7597 vSetAlarm(&g_cdvdman_power_off_timeout, power_off_alarm_cb, &g_cdvdman_istruct);
7598 return retval;
7599}
7600
7601int sceCdCtrlADout(int mode, u32 *status)
7602{
7603 char wdata[1];
7604
7605 *status = SCECdErNO;
7606 DelayThread(2000);
7607 VERBOSE_KPRINTF(1, "Audio Digital Out: Set param %d\n", (u8)mode);
7608 wdata[0] = mode;
7609 return set_prev_command(0x14, wdata, sizeof(wdata), (char *)status, 1, 1);
7610}
7611
7612#ifdef CDVD_VARIANT_OSD
7613// cppcheck-suppress funcArgNamesDifferent
7614int sceCdAutoAdjustCtrl(int mode, u32 *status)
7615{
7616 char wdata[1];
7617
7618 *status = SCECdErNO;
7619 DelayThread(2000);
7620 VERBOSE_KPRINTF(1, "Auto Adjust Ctrl: Set param %d\n", (u8)mode);
7621 wdata[0] = mode;
7622 return set_prev_command(0x16, wdata, sizeof(wdata), (char *)status, 1, 1);
7623}
7624
7625// TODO clock argument not const
7626int sceCdWriteWakeUpTime(const sceCdCLOCK *clock, u16 userdata, int flags)
7627{
7628 unsigned int clkmonth;
7629 unsigned int clkday;
7630 char wdata[8];
7631
7632 if ( !g_cdvdman_minver_50000 )
7633 {
7634 return 0;
7635 }
7636 clkmonth = 10 * (clock->month >> 4) + (clock->month & 0xF);
7637 clkday = 10 * (clock->day >> 4) + (clock->day & 0xF);
7638 if (
7639 (10 * (clock->second >> 4) + (clock->second & 0xF) >= 0x3C
7640 || 10 * (clock->minute >> 4) + (clock->minute & 0xF) >= 0x3C
7641 || 10 * (clock->hour >> 4) + (clock->hour & 0xF) >= 0x18 || 10 * (clock->year >> 4) + (clock->year & 0xF) >= 0x64
7642 || clkmonth >= 0xD || !clkmonth || clkday >= 0x20 || !clkday)
7643 && flags != 255 && !(clock->second & 0x80) && !(clock->minute & 0x80) )
7644 {
7645 return 0;
7646 }
7647 wdata[0] = (flags == 255) ? 255 : clock->second;
7648 wdata[1] = clock->minute | ((flags == 1) ? 0x80 : 0);
7649 wdata[2] = clock->hour;
7650 wdata[3] = clock->day;
7651 wdata[4] = clock->month;
7652 wdata[5] = clock->year;
7653 wdata[6] = userdata & 0xFF;
7654 wdata[7] = (userdata >> 8) & 0xFF;
7655 return set_prev_command(0x21, wdata, sizeof(wdata), (char *)&clock->stat, sizeof(clock->stat), 1);
7656}
7657
7658int sceCdReadWakeUpTime(sceCdCLOCK *clock, u16 *userdata, u32 *wakeupreason, int *flags)
7659{
7660 int retval;
7661 char rdata[10];
7662
7663 clock->year = 0;
7664 clock->month = 0;
7665 clock->day = 0;
7666 clock->pad = 0;
7667 clock->hour = 0;
7668 clock->minute = 0;
7669 clock->second = 0;
7670 clock->stat = 0;
7671 *userdata = 0;
7672 *wakeupreason = 0;
7673 *flags = 0;
7674 if ( !g_cdvdman_minver_50000 )
7675 {
7676 *wakeupreason = 256;
7677 return 1;
7678 }
7679 retval = set_prev_command(0x22, NULL, 0, rdata, sizeof(rdata), 1);
7680 if ( !retval )
7681 {
7682 return 0;
7683 }
7684 clock->stat = rdata[0];
7685 clock->second = (u8)rdata[2] == 255 ? -1 : (rdata[2] & 0x7F);
7686 clock->minute = rdata[3] & 0x7F;
7687 clock->pad = 0;
7688 clock->hour = rdata[4];
7689 clock->day = rdata[5];
7690 clock->month = rdata[6];
7691 clock->year = rdata[7];
7692 *userdata = (u8)rdata[8] | ((u8)rdata[9] << 8);
7693 *wakeupreason = (u8)rdata[1];
7694 *flags = (((u8)rdata[2] >> 7) << 1) | (!!(rdata[3] & 0x80));
7695 return retval;
7696}
7697
7698int sceCdSendSCmd1D(int *arg1, unsigned int *arg2, unsigned int *arg3, u32 *status)
7699{
7700 int retval;
7701 char rdata[5];
7702 u32 rdata2tmp;
7703
7704 *arg3 = 0;
7705 *arg2 = 0;
7706 *arg1 = 0;
7707 if ( !g_cdvdman_minver_50000 )
7708 {
7709 *status = 256;
7710 return 1;
7711 }
7712 *status = SCECdErNO;
7713 retval = set_prev_command(0x1D, NULL, 0, rdata, sizeof(rdata), 1);
7714 if ( retval != 1 )
7715 {
7716 return retval;
7717 }
7718 *status = (u8)rdata[0];
7719 *arg1 = (u8)rdata[1];
7720 rdata2tmp = rdata[4] | (rdata[3] << 8) | (rdata[2] << 16);
7721 switch ( *arg1 )
7722 {
7723 case 12:
7724 *arg2 = (rdata2tmp >> 17) & 0x7F;
7725 *arg3 = (rdata2tmp >> 12) & 0x1F;
7726 return 1;
7727 case 15:
7728 *arg2 = (rdata2tmp >> 17) & 0x7F;
7729 *arg3 = (rdata2tmp >> 9) & 0xFF;
7730 return 1;
7731 case 20:
7732 *arg2 = (rdata2tmp >> 17) & 0x7F;
7733 *arg3 = (rdata2tmp >> 4) & 0x1FFF;
7734 return 1;
7735 default:
7736 return 0;
7737 }
7738}
7739
7740int sceRemote2_7(u16 param, u32 *status)
7741{
7742 char wdata[2];
7743
7744 if ( !g_cdvdman_minver_50000 )
7745 {
7746 *status = 256;
7747 return 1;
7748 }
7749 *status = SCECdErNO;
7750 wdata[0] = param & 0xFF;
7751 wdata[1] = (param >> 8) & 0xFF;
7752 return set_prev_command(0x1F, wdata, sizeof(wdata), (char *)status, 1, 1);
7753}
7754
7755int sceRemote2_7Get(u32 *param, u32 *status)
7756{
7757 int retval;
7758 char rdata[3];
7759
7760 *param = 0;
7761 if ( !g_cdvdman_minver_50000 )
7762 {
7763 *status = 256;
7764 return 1;
7765 }
7766 *status = SCECdErNO;
7767 retval = set_prev_command(0x26, NULL, 0, rdata, sizeof(rdata), 1);
7768 *param = ((u8)rdata[2] << 8) | (u8)rdata[1];
7769 *status = (u8)rdata[0];
7770 return retval;
7771}
7772
7773// cppcheck-suppress funcArgNamesDifferent
7774int sceCdReadPS1BootParam(u8 *out, u32 *status)
7775{
7776 int retval;
7777 char rdata[13];
7778
7779 memset(out, 0, 11);
7780 if ( !g_cdvdman_minver_50200 )
7781 {
7782 *status = 256;
7783 return 1;
7784 }
7785 *status = SCECdErNO;
7786 retval = set_prev_command(0x27, NULL, 0, (char *)rdata, sizeof(rdata), 1);
7787 memcpy(out, &rdata[1], sizeof(rdata) - 2);
7788 *status = rdata[0];
7789 return retval;
7790}
7791
7792// cppcheck-suppress funcArgNamesDifferent
7793int sceCdSetFanProfile(u8 param, u32 *status)
7794{
7795 int retval;
7796 char rdata[1];
7797 char wdata[1];
7798
7799 if ( !g_cdvdman_minver_50400 )
7800 {
7801 *status = 256;
7802 return 1;
7803 }
7804 *status = SCECdErNO;
7805 wdata[0] = param;
7806 retval = set_prev_command(0x28, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7807 *status = (u8)rdata[0];
7808 return retval;
7809}
7810
7811int cdvdman_152(u32 *param, u32 *status)
7812{
7813 int retval;
7814 char rdata[3];
7815 char wdata[1];
7816
7817 if ( !g_cdvdman_minver_50400 )
7818 {
7819 *status = 256;
7820 *param = 0;
7821 return 1;
7822 }
7823 *status = SCECdErNO;
7824 wdata[0] = 0xEF;
7825 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7826 *param = 3125 * (((u8)rdata[2] | ((u8)rdata[1] << 8)) << 16 >> 18) / 100;
7827 *status = (u8)rdata[0];
7828 return retval;
7829}
7830#endif
7831
7832#ifdef CDVD_VARIANT_XOSD
7833// cppcheck-suppress funcArgNamesDifferent
7834int sceCdNoticeGameStart(u8 arg1, u32 *status)
7835{
7836 int retval;
7837 char rdata[1];
7838 char wdata[1];
7839
7840 if ( !g_cdvdman_minver_50400 )
7841 {
7842 *status = 256;
7843 return 1;
7844 }
7845 *status = SCECdErNO;
7846 wdata[0] = arg1;
7847 retval = set_prev_command(0x29, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7848 *status = (u8)rdata[0];
7849 if ( retval && !rdata[0] )
7850 {
7851 g_cdvdman_istruct.m_medium_removal_state = 0;
7852 }
7853 return retval;
7854}
7855#endif
7856
7857#ifdef CDVD_VARIANT_OSD
7858int sceCdRcBypassCtl(int mode, u32 *status)
7859{
7860 char wdata[1];
7861 USE_IOP_MMIO_HWPORT();
7862
7863 if ( mfc0(PRID) >= 0x23 )
7864 {
7865 if ( mode & 0xFF )
7866 {
7867 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] |= 1;
7868 }
7869 else
7870 {
7871 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] &= ~1;
7872 }
7873 *status = SCECdErNO;
7874 return 1;
7875 }
7876 if ( !g_cdvdman_minver_50000 )
7877 {
7878 *status = 256;
7879 return 1;
7880 }
7881 *status = SCECdErNO;
7882 wdata[0] = mode;
7883 return set_prev_command(0x24, wdata, sizeof(wdata), (char *)status, 1, 1);
7884}
7885
7886// cppcheck-suppress funcArgNamesDifferent
7887int sceCdReadRegionParams(u32 *param, u32 *status)
7888{
7889 int retval;
7890 char rdata[15];
7891
7892 memset(param, 0, 15);
7893 if ( !g_cdvdman_minver_60000 )
7894 {
7895 *status = 256;
7896 return 1;
7897 }
7898 *status = SCECdErNO;
7899 retval = set_prev_command(0x36, NULL, 0, rdata, sizeof(rdata), 1);
7900 memcpy(param, &rdata[1], sizeof(rdata) - 1);
7901 *status = rdata[0];
7902 return retval;
7903}
7904
7905// Not implemented XOSD or DVD Player 3.11
7906// TODO const arg2 arg3
7907// cppcheck-suppress funcArgNamesDifferent
7908int sceCdWriteRegionParams(u8 arg1, u32 *arg2, u8 *arg3, u32 *status)
7909{
7910 char wdata[15];
7911
7912 *status = SCECdErNO;
7913 memset(wdata, 0, sizeof(wdata));
7914 if ( !g_cdvdman_minver_60600 )
7915 {
7916 *status = 256;
7917 return 1;
7918 }
7919 wdata[0] = arg1;
7920 // The following was inlined
7921 memcpy(&wdata[1], arg2, 12);
7922 // The following was inlined
7923 memcpy(&wdata[13], arg3, 2);
7924 return set_prev_command(0x3E, wdata, sizeof(wdata), (char *)status, 1, 1);
7925}
7926
7927// cppcheck-suppress funcArgNamesDifferent
7928int sceCdSetLEDsMode(u32 param, u32 *status)
7929{
7930 char wdata[1];
7931
7932 if ( !g_cdvdman_minver_50000 )
7933 {
7934 *status = 256;
7935 return 1;
7936 }
7937 *status = SCECdErNO;
7938 wdata[0] = param;
7939 return set_prev_command(0x25, wdata, sizeof(wdata), (char *)status, 1, 1);
7940}
7941#endif
7942
7944{
7945 int retval;
7946
7947 retval = set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7948 clock->pad = 0;
7949 clock->month &= 0x7F;
7950 if ( retval && !clock->stat )
7951 {
7952 memcpy(&g_cdvdman_clock, clock, sizeof(g_cdvdman_clock));
7953 g_cdvdman_clk_flg = 1;
7954 }
7955 else if ( g_cdvdman_clk_flg )
7956 {
7957 memcpy(clock, &g_cdvdman_clock, sizeof(g_cdvdman_clock));
7958 }
7959 else
7960 {
7961 clock->month = 3;
7962 clock->day = 4;
7963 clock->hour = 5;
7964 clock->minute = 6;
7965 clock->year = 0;
7966 clock->second = 7;
7967 }
7968 return retval;
7969}
7970
7971int sceCdRC(sceCdCLOCK *clock)
7972{
7973 return set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7974}
7975
7976#ifdef CDVD_VARIANT_OSD
7977int sceCdWriteClock(sceCdCLOCK *clock)
7978{
7979 return set_prev_command(
7980 0x09, (const char *)&clock->second, sizeof(clock) - 1, (char *)&clock->stat, sizeof(clock->second), 1);
7981}
7982
7983int sceCdReadNVM(u32 address, u16 *data, u8 *result)
7984{
7985 int retval;
7986 char rdata[3];
7987 char wdata[2];
7988
7989 wdata[0] = (address >> 8) & 0xFF;
7990 wdata[1] = address & 0xFF;
7991 retval = set_prev_command(0x0A, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7992 *result = rdata[0];
7993 *data = (rdata[1] << 8) | rdata[2];
7994 VERBOSE_KPRINTF(1, "RN_call addr= 0x%04x data= 0x%04x stat= 0x%02x\n", address, *data, *result);
7995 return retval;
7996}
7997
7998int sceCdWriteNVM(u32 address, u16 data, u8 *result)
7999{
8000 int retval;
8001 char wdata[4];
8002
8003 wdata[0] = (address >> 8) & 0xFF;
8004 wdata[1] = address & 0xFF;
8005 wdata[2] = (data >> 8) & 0xFF;
8006 wdata[3] = data & 0xFF;
8007 retval = set_prev_command(0x0B, wdata, sizeof(wdata), (char *)result, 1, 1);
8008 VERBOSE_KPRINTF(1, "WN_call addr= 0x%04x data= 0x%04x stat= 0x%02x\n", address, data, *result);
8009 return retval;
8010}
8011#endif
8012
8013int sceCdTrayReq(int param, u32 *traychk)
8014{
8015 char wdata[1];
8016 char rdata[1];
8017#ifdef CDVD_VARIANT_XOSD
8018 int state;
8019#endif
8020
8021 if ( param == SCECdTrayCheck )
8022 {
8023 *traychk = cdvdman_mediactl(1);
8024 VERBOSE_KPRINTF(1, "Tray Req test = %d\n", *traychk);
8025 return 1;
8026 }
8027 if ( g_cdvdman_minver_x_model_15 && param == SCECdTrayClose )
8028 {
8029 return 1;
8030 }
8031 wdata[0] = param;
8032 g_cdvdman_iocache = 0;
8033#ifdef CDVD_VARIANT_XOSD
8034 CpuSuspendIntr(&state);
8035#endif
8036 rdata[0] = !!set_prev_command(0x06, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0];
8037#ifdef CDVD_VARIANT_XOSD
8038 CpuResumeIntr(state);
8039#endif
8040 if ( rdata[0] )
8041 {
8042#ifdef CDVD_VARIANT_XOSD
8043 if ( !param )
8044 {
8045 g_cdvdman_istruct.m_medium_removal_state = 0;
8046 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
8047 }
8048#endif
8049 vDelayThread(11000);
8050 }
8051 return rdata[0];
8052}
8053
8054static int cdvdman_scmd_sender_3B(int arg1)
8055{
8056 char wdata[1];
8057 char rdata[1];
8058
8059 if ( g_cdvdman_minver_x_model_15 && arg1 == 1 )
8060 {
8061 return 1;
8062 }
8063 g_cdvdman_iocache = 0;
8064 wdata[0] = arg1;
8065 if ( set_prev_command(0x3B, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0] )
8066 {
8067 vDelayThread(11000);
8068 return 1;
8069 }
8070 return 0;
8071}
8072
8073#ifdef CDVD_VARIANT_DNAS
8074int sceCdReadDiskID(unsigned int *id)
8075{
8076 sceCdRMode rmode;
8077 char sectbuf[0x800];
8078 u32 efbits;
8079 USE_DEV5_MMIO_HWPORT();
8080
8081 // The following was inlined
8082 memset(id, 0, 5);
8083#ifdef CDVD_VARIANT_XOSD
8084 switch ( get_disk_type_ex() )
8085#else
8086 switch ( sceCdGetDiskType() )
8087#endif
8088 {
8089 case SCECdPS2CD:
8090 case SCECdPS2CDDA:
8091 case SCECdPS2DVD:
8092 break;
8093 default:
8094 return 0;
8095 }
8096 rmode.spindlctrl = 0x12;
8097 rmode.datapattern = SCECdSecS2048;
8098 rmode.trycount = 0;
8099 sceCdRead0(0x4B, 1, sectbuf, &rmode, 0, 0);
8100 sceCdSync(3);
8101 if ( !cdvdman_ncmd_sender_0C(0, 0, 0x4B) )
8102 {
8103 return 0;
8104 }
8105 sceCdSync(3);
8106 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8107 {
8108 return 0;
8109 }
8110 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8111 if ( !(dev5_mmio_hwport->m_dev5_reg_038 & 4) )
8112 {
8113 vSetEventFlag(g_scmd_evfid, 1);
8114 return 0;
8115 }
8116 *(u8 *)id = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
8117 *((u8 *)id + 1) = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
8118 *((u8 *)id + 2) = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
8119 *((u8 *)id + 3) = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
8120 *((u8 *)id + 4) = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
8121 vSetEventFlag(g_scmd_evfid, 1);
8122 return 1;
8123}
8124
8125int sceCdDoesUniqueKeyExist(u32 *status)
8126{
8127 int is_cd;
8128 u8 dev5_reg_038;
8129 sceCdRMode rmode;
8130 char ndata[7];
8131 int state;
8132 u32 efbits;
8133 USE_DEV5_MMIO_HWPORT();
8134
8135 if ( !g_cdvdman_istruct.m_cd_inited )
8136 {
8137 *status = SCECdErCUD;
8138 return 0;
8139 }
8140 *status = SCECdErNO;
8141#ifdef CDVD_VARIANT_XOSD
8142 switch ( get_disk_type_ex() )
8143#else
8144 switch ( sceCdGetDiskType() )
8145#endif
8146 {
8147 case SCECdPS2CD:
8148 case SCECdPS2CDDA:
8149 is_cd = 1;
8150 break;
8151 case SCECdPS2DVD:
8152 is_cd = 0;
8153 break;
8154 default:
8155 *status = SCECdErCUD;
8156 return 0;
8157 }
8158 CpuSuspendIntr(&state);
8159 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8160 {
8161 *status = SCECdErREADCF;
8162 CpuResumeIntr(state);
8163 return 0;
8164 }
8165 if ( (sceCdStatus() & SCECdStatSpin) )
8166 {
8167 CpuResumeIntr(state);
8168 }
8169 else
8170 {
8171 dev5_mmio_hwport->m_dev5_reg_007 = 1;
8172 CpuResumeIntr(state);
8173 sceCdSync(3);
8174 }
8175 CpuSuspendIntr(&state);
8176 rmode.spindlctrl = 0x12;
8177 rmode.datapattern = SCECdSecS2048;
8178 rmode.trycount = 0;
8179 if ( is_cd )
8180 {
8181 unsigned int i;
8182
8183 for ( i = 0; i < 20; i += 1 )
8184 {
8185 sceCdRead0(0x4B + (0x10 * i), 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
8186 CpuResumeIntr(state);
8187 sceCdSync(3);
8188 CpuSuspendIntr(&state);
8189 }
8190 CpuResumeIntr(state);
8191 }
8192 else
8193 {
8194 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
8195 CpuResumeIntr(state);
8196 sceCdSync(3);
8197 }
8198 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8199 CpuSuspendIntr(&state);
8200 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8201 {
8202 *status = SCECdErREADCF;
8203 CpuResumeIntr(state);
8204 vSetEventFlag(g_scmd_evfid, 1);
8205 return 0;
8206 }
8207 // The following was inlined
8208 memset(ndata, 0, sizeof(ndata));
8209 ndata[3] = 0x4B;
8210 if ( cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) < 0 )
8211 {
8212 *status = SCECdErREADCF;
8213 CpuResumeIntr(state);
8214 vSetEventFlag(g_scmd_evfid, 1);
8215 return 0;
8216 }
8217 CpuResumeIntr(state);
8218 sceCdSync(3);
8219 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8220 {
8221 *status = (u8)g_cdvdman_istruct.m_last_error;
8222 vSetEventFlag(g_scmd_evfid, 1);
8223 return 0;
8224 }
8225 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
8226 vSetEventFlag(g_scmd_evfid, 1);
8227 return (dev5_reg_038 & 5) == 5;
8228}
8229#endif
8230
8231#ifdef CDVD_VARIANT_XOSD
8232int sceCdDeobfuscateUsingUniqueKey(u8 *buffer, unsigned int shiftval, int xorval, u32 *status)
8233{
8234 int is_cd;
8235 int retval;
8236 int i;
8237 u8 xor_val_1_stk;
8238 u8 xor_val_2_stk;
8239 u8 xor_val_3_stk;
8240 u8 xor_val_4_stk;
8241 u8 xor_val_1_xstk;
8242 u8 xor_val_2_xstk;
8243 char xorarea[16];
8244 char ndata[7];
8245 sceCdRMode rmode;
8246 int state;
8247 u32 efbits;
8248 USE_DEV5_MMIO_HWPORT();
8249
8250 memset(xorarea, 0, sizeof(xorarea));
8251 memset(buffer, 0, 16);
8252 *status = SCECdErNO;
8253 if ( shiftval >= 8 || xorval < 0 || xorval >= 256 )
8254 {
8255 *status = SCECdErREADCF;
8256 return 0;
8257 }
8258 if ( !g_cdvdman_istruct.m_cd_inited )
8259 {
8260 *status = SCECdErCUD;
8261 return 0;
8262 }
8263 switch ( get_disk_type_ex() )
8264 {
8265 case SCECdPS2CD:
8266 case SCECdPS2CDDA:
8267 is_cd = 1;
8268 break;
8269 case SCECdPS2DVD:
8270 is_cd = 0;
8271 break;
8272 default:
8273 *status = SCECdErCUD;
8274 return 0;
8275 }
8276 CpuSuspendIntr(&state);
8277 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8278 {
8279 *status = SCECdErREADCF;
8280 CpuResumeIntr(state);
8281 return 0;
8282 }
8283 if ( !(sceCdStatus() & SCECdStatSpin) )
8284 {
8285 dev5_mmio_hwport->m_dev5_reg_007 = 1;
8286 CpuResumeIntr(state);
8287 sceCdSync(3);
8288 CpuSuspendIntr(&state);
8289 }
8290 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8291 {
8292 *status = SCECdErREADCF;
8293 CpuResumeIntr(state);
8294 return 0;
8295 }
8296 rmode.spindlctrl = 0x12;
8297 rmode.datapattern = SCECdSecS2048;
8298 rmode.trycount = 0;
8299 if ( is_cd )
8300 {
8301 for ( i = 0; i < 0x14; i += 1 )
8302 {
8303 sceCdRead0(75 + 16 * i, 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
8304 CpuResumeIntr(state);
8305 sceCdSync(3);
8306 CpuSuspendIntr(&state);
8307 }
8308 CpuResumeIntr(state);
8309 }
8310 else
8311 {
8312 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
8313 CpuResumeIntr(state);
8314 sceCdSync(3);
8315 }
8316 WaitEventFlag(g_scmd_evfid, 1, 0, &efbits);
8317 CpuSuspendIntr(&state);
8318 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8319 {
8320 *status = SCECdErREADCF;
8321 CpuResumeIntr(state);
8322 vSetEventFlag(g_scmd_evfid, 1);
8323 return 0;
8324 }
8325 // The following was inlined
8326 memset(ndata, 0, sizeof(ndata));
8327 ndata[3] = 0x4B;
8328 if ( cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) < 0 )
8329 {
8330 *status = SCECdErREADCF;
8331 CpuResumeIntr(state);
8332 vSetEventFlag(g_scmd_evfid, 1);
8333 return 0;
8334 }
8335 CpuResumeIntr(state);
8336 sceCdSync(3);
8337 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8338 {
8339 *status = (u8)g_cdvdman_istruct.m_last_error;
8340 vSetEventFlag(g_scmd_evfid, 1);
8341 return 0;
8342 }
8343 retval = 0;
8344 xor_val_2_xstk = 0;
8345 xor_val_1_xstk = 0;
8346 xor_val_4_stk = 0;
8347 xor_val_3_stk = 0;
8348 xor_val_2_stk = 0;
8349 xor_val_1_stk = 0;
8350 if ( (dev5_mmio_hwport->m_dev5_reg_038 & 5) == 5 )
8351 {
8352 u8 dev5_reg_020;
8353 u8 dev5_reg_039;
8354 u8 dev5_reg_022;
8355 u8 reg_039_tmp1;
8356
8357 dev5_reg_020 = dev5_mmio_hwport->m_dev5_reg_020;
8358 dev5_reg_039 = dev5_mmio_hwport->m_dev5_reg_039;
8359 xor_val_1_stk = dev5_reg_020 ^ dev5_reg_039;
8360 xor_val_2_stk = dev5_reg_039 ^ dev5_mmio_hwport->m_dev5_reg_021;
8361 dev5_reg_022 = dev5_mmio_hwport->m_dev5_reg_022;
8362 reg_039_tmp1 = dev5_mmio_hwport->m_dev5_reg_039;
8363 xor_val_3_stk = dev5_reg_022 ^ reg_039_tmp1;
8364 xor_val_4_stk = reg_039_tmp1 ^ dev5_mmio_hwport->m_dev5_reg_023;
8365 xor_val_1_xstk = dev5_mmio_hwport->m_dev5_reg_024 ^ dev5_mmio_hwport->m_dev5_reg_039;
8366 xor_val_2_xstk = dev5_mmio_hwport->m_dev5_reg_039 ^ dev5_mmio_hwport->m_dev5_reg_034;
8367 retval = 1;
8368 }
8369 vSetEventFlag(g_scmd_evfid, 1);
8370 xorarea[0] = (xor_val_4_stk >> 4) | ((xor_val_1_xstk << 4) & 0x70);
8371 xorarea[1] = (xor_val_3_stk >> 5) | ((xor_val_4_stk << 3) & 0x78);
8372 xorarea[2] = (xor_val_2_stk >> 6) | ((xor_val_3_stk << 2) & 0x7C);
8373 xorarea[3] = (xor_val_1_stk >> 7) | ((xor_val_2_stk << 1) & 0x7E);
8374 sprintf(&xorarea[4], "%d", ((xor_val_1_stk & 0x7F) << 10) | (xor_val_1_xstk >> 3) | ((xor_val_2_xstk >> 3) << 5));
8375 for ( i = 0; i < 9; i += 1 )
8376 {
8377 xorarea[i] = xorarea[i] ^ xorval;
8378 }
8379 if ( shiftval )
8380 {
8381 for ( i = 0; i < 9; i += 1 )
8382 {
8383 buffer[i] = (xorarea[i] << shiftval) | ((int)(u8)xorarea[i ? i - 1 : 8] >> (8 - shiftval));
8384 }
8385 }
8386 else
8387 {
8388 // The following was inlined
8389 memcpy(buffer, xorarea, sizeof(xorarea));
8390 }
8391 return retval;
8392}
8393#endif
8394
8395#ifdef CDVD_VARIANT_OSD
8396int sceCdReadKey(u8 arg1, u8 arg2, unsigned int command, u8 *key)
8397{
8398 int i;
8399 u8 dev5_reg_038;
8400 sceCdRMode rmode;
8401 char sectorbuf[0x800];
8402 u32 efbits;
8403 USE_DEV5_MMIO_HWPORT();
8404
8405 if ( cdvdman_isdvd() && !arg1 )
8406 {
8407 if ( !DvdDual_infochk() )
8408 {
8409 return 0;
8410 }
8411 command = sceCdLsnDualChg(command);
8412 }
8413 rmode.spindlctrl = 0x12;
8414 rmode.datapattern = SCECdSecS2048;
8415 rmode.trycount = 0;
8416 sceCdRead0(command, 1, sectorbuf, &rmode, 0, 0);
8417 sceCdSync(3);
8418 for ( i = 0; i < 300; i += 1 )
8419 {
8420 if ( !cdvdman_ncmd_sender_0C(arg1, arg2, command + i) )
8421 {
8422 return 0;
8423 }
8424 sceCdSync(3);
8425 if ( g_cdvdman_istruct.m_last_error == SCECdErNO )
8426 {
8427 break;
8428 }
8429 }
8430 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8431 // The following was inlined
8432 memset(key, 0, 16);
8433 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
8434 if ( (dev5_reg_038 & 1) )
8435 {
8436 key[0] = dev5_mmio_hwport->m_dev5_reg_020 ^ dev5_mmio_hwport->m_dev5_reg_039;
8437 key[1] = dev5_mmio_hwport->m_dev5_reg_021 ^ dev5_mmio_hwport->m_dev5_reg_039;
8438 key[2] = dev5_mmio_hwport->m_dev5_reg_022 ^ dev5_mmio_hwport->m_dev5_reg_039;
8439 key[3] = dev5_mmio_hwport->m_dev5_reg_023 ^ dev5_mmio_hwport->m_dev5_reg_039;
8440 key[4] = dev5_mmio_hwport->m_dev5_reg_024 ^ dev5_mmio_hwport->m_dev5_reg_039;
8441 }
8442 if ( (dev5_reg_038 & 2) )
8443 {
8444 key[5] = dev5_mmio_hwport->m_dev5_reg_028 ^ dev5_mmio_hwport->m_dev5_reg_039;
8445 key[6] = dev5_mmio_hwport->m_dev5_reg_029 ^ dev5_mmio_hwport->m_dev5_reg_039;
8446 key[7] = dev5_mmio_hwport->m_dev5_reg_02A ^ dev5_mmio_hwport->m_dev5_reg_039;
8447 key[8] = dev5_mmio_hwport->m_dev5_reg_02B ^ dev5_mmio_hwport->m_dev5_reg_039;
8448 key[9] = dev5_mmio_hwport->m_dev5_reg_02C ^ dev5_mmio_hwport->m_dev5_reg_039;
8449 }
8450 if ( (dev5_reg_038 & 4) )
8451 {
8452 key[10] = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
8453 key[11] = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
8454 key[12] = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
8455 key[13] = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
8456 key[14] = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
8457 }
8458 key[15] = dev5_reg_038 & 7;
8459 vSetEventFlag(g_scmd_evfid, 1);
8460 return 1;
8461}
8462#endif
8463
8464#ifdef CDVD_VARIANT_DNAS
8465static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3)
8466{
8467 char ndata[7];
8468
8469 ndata[1] = !!arg2;
8470 ndata[0] = arg1;
8471 ndata[2] = !!(arg2 >> 8);
8472 *(u32 *)&ndata[3] = !arg1 ? arg3 : 0;
8473 return cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) >= 0;
8474}
8475#endif
8476
8477int sceCdDecSet(u8 enable_xor, u8 enable_shift, u8 shiftval)
8478{
8479#ifdef CDVD_VARIANT_DNAS
8480 USE_DEV5_MMIO_HWPORT();
8481
8482 g_cdvdman_cd36key = enable_shift | shiftval;
8483 dev5_mmio_hwport->m_dev5_reg_03A = ((shiftval & 7) << 4) | ((!!enable_xor) << 1) | (!!enable_shift);
8484#else
8485 (void)enable_xor;
8486 (void)enable_shift;
8487 (void)shiftval;
8488#endif
8489 return 1;
8490}
8491
8492#ifdef CDVD_VARIANT_OSD
8493int sceCdOpenConfig(int block, int mode, int NumBlocks, u32 *status)
8494{
8495 int retval;
8496#ifdef CDVD_VARIANT_XOSD
8497 u32 efbits;
8498#endif
8499 char wdata[3];
8500
8501#ifdef CDVD_VARIANT_XOSD
8502 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8503 {
8504 return 0;
8505 }
8506#endif
8507 DelayThread(16000);
8508 *status = SCECdErNO;
8509 wdata[0] = (u8)mode;
8510 wdata[1] = (u8)block;
8511 wdata[2] = (u8)NumBlocks;
8512 retval = set_prev_command(0x40, wdata, sizeof(wdata), (char *)status, 1, 0);
8513#ifdef CDVD_VARIANT_XOSD
8514 if ( retval == 1 )
8515#endif
8516 {
8517 g_cdvdman_config_numblocks = NumBlocks;
8518 }
8519#ifdef CDVD_VARIANT_XOSD
8520 vSetEventFlag(g_scmd_evfid, 1);
8521#endif
8522 return retval;
8523}
8524
8525// cppcheck-suppress funcArgNamesDifferent
8526int sceCdCloseConfig(u32 *status)
8527{
8528 int retval;
8529
8530 *status = SCECdErNO;
8531 DelayThread(16000);
8532 retval = set_prev_command(0x43, NULL, 0, (char *)status, 1, 1);
8533 g_cdvdman_config_numblocks = 0;
8534 return retval;
8535}
8536
8537static int read_config_process(char *outval, u32 *status)
8538{
8539 int retval;
8540 char rdata[16];
8541
8542 DelayThread(2000);
8543 retval = set_prev_command(0x41, NULL, 0, rdata, sizeof(rdata), 0);
8544 *status = (u8)(rdata[14] + rdata[13] + rdata[12] + rdata[11] + rdata[10] + rdata[9] + rdata[8] + rdata[7] + rdata[6]
8545 + rdata[5] + rdata[4] + rdata[3] + rdata[2] + rdata[0] + rdata[1])
8546 != (u8)rdata[15];
8547 memcpy(outval, rdata, sizeof(rdata) - 1);
8548 return retval;
8549}
8550
8551// cppcheck-suppress funcArgNamesDifferent
8552int sceCdReadConfig(void *buffer, u32 *status)
8553{
8554 int retval;
8555 u32 efbits;
8556
8557 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8558 {
8559 return 0;
8560 }
8561 for ( retval = 0; retval < g_cdvdman_config_numblocks; retval += 1 )
8562 {
8563 if ( !read_config_process((char *)buffer + 15 * retval, status) )
8564 {
8565 VERBOSE_KPRINTF(1, "RC_fail Command busy\n");
8566 break;
8567 }
8568 if ( *status )
8569 {
8570 VERBOSE_KPRINTF(1, "RC_fail status: 0x%02x\n", *status);
8571 break;
8572 }
8573 }
8574 vSetEventFlag(g_scmd_evfid, 1);
8575 return retval;
8576}
8577
8578static int write_config_process(const char *inval, u32 *status)
8579{
8580 char wdata[16];
8581
8582 DelayThread(2000);
8583 *status = SCECdErNO;
8584 memcpy(wdata, inval, 15);
8585 wdata[15] = wdata[14] + wdata[13] + wdata[12] + wdata[11] + wdata[10] + wdata[9] + wdata[8] + wdata[7] + wdata[6]
8586 + wdata[5] + wdata[4] + wdata[3] + wdata[2] + wdata[0] + wdata[1];
8587 return set_prev_command(0x42, wdata, sizeof(wdata), (char *)status, 1, 0);
8588}
8589
8590// cppcheck-suppress funcArgNamesDifferent
8591int sceCdWriteConfig(const void *buffer, u32 *status)
8592{
8593 int retval;
8594 u32 efbits;
8595
8596 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8597 {
8598 return 0;
8599 }
8600 for ( retval = 0; retval < g_cdvdman_config_numblocks; retval += 1 )
8601 {
8602 if ( !write_config_process((char *)buffer + 15 * retval, status) )
8603 {
8604 VERBOSE_KPRINTF(1, "WC_fail Command busy\n");
8605 break;
8606 }
8607 if ( *status )
8608 {
8609 VERBOSE_KPRINTF(1, "WC_fail status: 0x%02x\n", *status);
8610 break;
8611 }
8612 }
8613 vSetEventFlag(g_scmd_evfid, 1);
8614 return retval;
8615}
8616
8617int sceCdSetHDMode(u32 mode)
8618{
8619 char wdata[1];
8620 char rdata[1];
8621
8622 wdata[0] = mode;
8623 return set_prev_command(0x0C, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0];
8624}
8625#endif
8626
8627#ifdef CDVD_VARIANT_XOSD
8628// cppcheck-suppress funcArgNamesDifferent
8629int sceCdXLEDCtl(u8 arg1, u8 arg2, u32 *param, u32 *status)
8630{
8631 int retval;
8632 char wdata[2];
8633 char rdata[2];
8634
8635 *param = 0;
8636 if ( !g_cdvdman_minver_50600 )
8637 {
8638 *status = 256;
8639 return 1;
8640 }
8641 *status = SCECdErNO;
8642 wdata[0] = arg1;
8643 wdata[1] = arg2;
8644 retval = set_prev_command(0x2D, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
8645 if ( !retval )
8646 {
8647 return 0;
8648 }
8649 *status = (u8)rdata[0];
8650 *param = (u8)rdata[1];
8651 return retval;
8652}
8653#endif
8654
8655#ifdef CDVD_VARIANT_XOSD
8656// cppcheck-suppress funcArgNamesDifferent
8657int sceCdBuzzerCtl(u32 *status)
8658{
8659 if ( !g_cdvdman_minver_50600 )
8660 {
8661 *status = 256;
8662 return 1;
8663 }
8664 *status = SCECdErNO;
8665 return set_prev_command(0x2E, NULL, 0, (char *)status, 1, 1);
8666}
8667#endif
8668
8669#ifdef CDVD_VARIANT_XOSD
8670int sceCdResetWakeupReason(u32 *inbuf, u32 *status)
8671{
8672 if ( !g_cdvdman_minver_50600 )
8673 {
8674 *status = 256;
8675 return 1;
8676 }
8677 *status = SCECdErNO;
8678 return cdvdman_write_scmd_swap_dev5(0x2F, (char *)inbuf, 16, (char *)status, 1, 1);
8679}
8680#endif
8681
8682#ifdef CDVD_VARIANT_XOSD
8683int cdvdman_169(u32 *arg1, u32 *status)
8684{
8685 int i;
8686 int retval;
8687 char rdata[9];
8688 u32 efbits;
8689 char wdata[1];
8690
8691 if ( !g_cdvdman_minver_50600 )
8692 {
8693 *status = 256;
8694 return 1;
8695 }
8696 *status = SCECdErNO;
8697 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8698 {
8699 return 0;
8700 }
8701 memset(arg1, 0, 16);
8702 if ( *status )
8703 {
8704 vSetEventFlag(g_scmd_evfid, 1);
8705 return 1;
8706 }
8707 retval = 0;
8708 for ( i = 0; i < 2 && !rdata[0]; i += 1 )
8709 {
8710 wdata[0] = i * 8;
8711 retval = 0;
8712 while ( !retval )
8713 {
8714 DelayThread(2000);
8715 retval = cdvdman_write_scmd_swap_dev5(0x30, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
8716 memcpy(&arg1[i * 2], &rdata[1], sizeof(rdata) - 1);
8717 *status = rdata[0];
8718 }
8719 }
8720 return retval;
8721}
8722#endif
8723
8724#ifdef CDVD_VARIANT_XOSD
8725// cppcheck-suppress funcArgNamesDifferent
8726int sceCdXBSPowerCtl(u8 arg1, u8 arg2, u32 *param, u32 *status)
8727{
8728 int retval;
8729 char wdata[2];
8730 char rdata[2];
8731
8732 *param = 0;
8733 if ( !g_cdvdman_minver_50600 )
8734 {
8735 *status = 256;
8736 return 1;
8737 }
8738 *status = SCECdErNO;
8739 wdata[0] = arg1;
8740 wdata[1] = arg2;
8741 retval = set_prev_command(0x2C, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
8742 if ( !retval )
8743 {
8744 return 0;
8745 }
8746 *status = (u8)rdata[0];
8747 *param = (u8)rdata[1];
8748 return retval;
8749}
8750#endif
8751
8752#ifdef CDVD_VARIANT_XOSD
8753// cppcheck-suppress funcArgNamesDifferent
8754int sceCdSetMediumRemoval(u8 wanted_val, u32 *status)
8755{
8756 int retval;
8757 int saved_medium_removal_state;
8758 char wdata[1];
8759 int state;
8760
8761 if ( !g_cdvdman_minver_50600 )
8762 {
8763 *status = 256;
8764 return 1;
8765 }
8766 *status = SCECdErNO;
8767 CpuSuspendIntr(&state);
8768 saved_medium_removal_state = g_cdvdman_istruct.m_medium_removal_state;
8769 g_cdvdman_istruct.m_medium_removal_state = (u8)wanted_val;
8770 wdata[0] = wanted_val;
8771 retval = set_prev_command(0x31, wdata, sizeof(wdata), (char *)status, 1, 1);
8772 if ( !retval || *status )
8773 {
8774 g_cdvdman_istruct.m_medium_removal_state = saved_medium_removal_state;
8775 }
8776 CpuResumeIntr(state);
8777 return retval;
8778}
8779#endif
8780
8781#ifdef CDVD_VARIANT_XOSD
8782// cppcheck-suppress funcArgNamesDifferent
8783int sceCdGetMediumRemoval(u32 *param, u32 *status)
8784{
8785 int retval;
8786 char rdata[2];
8787
8788 *param = 0;
8789 if ( !g_cdvdman_minver_50600 )
8790 {
8791 *status = 256;
8792 return 1;
8793 }
8794 *status = SCECdErNO;
8795 retval = set_prev_command(0x32, NULL, 0, rdata, sizeof(rdata), 1);
8796 if ( !retval )
8797 {
8798 return 0;
8799 }
8800 *status = (u8)rdata[0];
8801 *param = (u8)rdata[1];
8802 if ( !rdata[0] )
8803 {
8804 g_cdvdman_istruct.m_medium_removal_state = *param;
8805 }
8806 return retval;
8807}
8808#endif
8809
8810#ifdef CDVD_VARIANT_XOSD
8811// cppcheck-suppress funcArgNamesDifferent
8812int sceCdXDVRPReset(u8 arg1, u32 *status)
8813{
8814 char wdata[1];
8815
8816 if ( !g_cdvdman_minver_50600 )
8817 {
8818 *status = 256;
8819 return 1;
8820 }
8821 *status = SCECdErNO;
8822 wdata[0] = arg1;
8823 return set_prev_command(0x33, wdata, sizeof(wdata), (char *)status, 1, 1);
8824}
8825#endif
8826
8827#ifdef CDVD_VARIANT_XOSD
8828static int sc_ffffffd8(u32 *status)
8829{
8830 int retval;
8831
8832 if ( !g_cdvdman_minver_50600 )
8833 {
8834 *status = 256;
8835 return 1;
8836 }
8837 *status = SCECdErNO;
8838 retval = set_prev_command(0x34, NULL, 0, (char *)status, 1, 1);
8839 if ( !retval )
8840 {
8841 return 0;
8842 }
8843 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
8844 return retval;
8845}
8846#endif
8847
8848#ifdef CDVD_VARIANT_XOSD
8849#ifdef DEAD_CODE
8850int cdvdman_scmd_sender_35(u32 *param, u32 *status)
8851{
8852 int retval;
8853 char rdata[2];
8854
8855 *param = 0;
8856 if ( !g_cdvdman_minver_50600 )
8857 {
8858 *status = 256;
8859 return 1;
8860 }
8861 *status = SCECdErNO;
8862 retval = set_prev_command(0x35, NULL, 0, rdata, sizeof(rdata), 1);
8863 if ( !retval )
8864 {
8865 return 0;
8866 }
8867 *status = (u8)rdata[0];
8868 *param = (u8)rdata[1];
8869 return retval;
8870}
8871#endif
8872#endif
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:7136
int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
Definition cdvdman.c:5450
int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
int sceCdSpinCtrlIOP(u32 speed)
Definition cdvdman.c:2192
int sceCdReadDiskID(unsigned int *id)
int sceCdDeobfuscateUsingUniqueKey(u8 *buffer, unsigned int shiftval, int xorval, u32 *status)
void * sceCdSetAtapiEjectCallback(int(*cb)(int reason, void *userdata), void *userdata)
#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:2577
char name[16]
void * sceCdPOffCallback(void(*func)(void *), void *addr)
Definition cdvdman.c:3879
int sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition cdi.c:114
int sceCdXLEDCtl(u8 arg1, u8 arg2, u32 *result1, u32 *result2)
int sceCdGetError(void)
Definition cdi.c:40
int sceCdRcBypassCtl(int mode, u32 *status)
@ STMNBLK
int sceCdStatus2(void)
int sceCdCancelPOffRdy(u32 *result)
Definition cdvdman.c:7540
int sceCdReadRegionParams(u32 *arg1, u32 *result)
int sceCdPowerOff(u32 *result)
Definition cdvdman.c:7569
int sceRemote2_7(u16 param, u32 *status)
int sceCdSetFanProfile(u8 param, u32 *result)
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 sceCdGetMediumRemoval(u32 *result1, u32 *result2)
int sceCdReadSUBQ(void *buffer, u32 *status)
int sceCdSetHDMode(u32 mode)
int sceCdReadKey(unsigned char arg1, unsigned char arg2, unsigned int command, unsigned char *key)
int sceCdGetToc(u8 *toc)
Definition cdi.c:57
int sceCdInit(int mode)
Definition cdi.c:64
int sceCdReadNVM(u32 address, u16 *data, u8 *result)
sceCdCBFunc sceCdCallback(sceCdCBFunc function)
Definition cdi.c:16
int sceCdReadPS1BootParam(u8 *out, u32 *result)
int sceCdXDVRPReset(u8 arg1, u32 *result)
int sceCdSetMediumRemoval(u8 arg1, u32 *result)
int sceCdSendSCmd1D(int *arg1, unsigned int *arg2, unsigned int *arg3, u32 *status)
int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
Definition cdvdman.c:4526
int sceCdCloseConfig(u32 *result)
int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
Definition cdi.c:167
int sceCdGetToc2(u8 *toc, int param)
int sceCdStatus(void)
Definition cdi.c:152
int sceCdReadGUID(u64 *guid)
int sceCdDiskReady(int mode)
Definition cdi.c:30
int sceCdForbidRead(u32 *result)
int sceCdPause(void)
Definition cdi.c:93
int sceCdRM(char *buffer, u32 *status)
Definition cdvdman.c:7288
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition cdvdman.c:2420
int sceCdReadConsoleID(u8 *buffer, u32 *result)
int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
Definition cdvdman.c:2199
int sceCdReadClock(sceCdCLOCK *clock)
Definition cdvdman.c:7943
int sceCdWriteConfig(const void *buffer, u32 *result)
int sceCdWM(const char *buffer, u32 *status)
int sceCdWriteConsoleID(const u8 *buffer, u32 *status)
u32 sceCdGetReadPos(void)
Definition cdi.c:45
int sceCdGetDiskType(void)
Definition cdi.c:35
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
Definition cdvdman.c:2411
int sceCdGetWakeUpReason(void)
int sceCdMmode(int media)
Definition cdi.c:86
int sceCdSync(int mode)
Definition cdi.c:109
int sceCdWI(const u8 *buffer, u32 *result)
int sceCdStResume(void)
Definition cdi.c:224
int sceCdAutoAdjustCtrl(int mode, u32 *result)
int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
Definition cdvdman.c:5414
int sceCdXBSPowerCtl(u8 arg1, u8 arg2, u32 *result1, u32 *result2)
int sceRemote2_7Get(u32 *param, u32 *status)
int sceCdSeek(u32 lbn)
Definition cdi.c:142
int sceCdSetTimeout(int param, int timeout)
Definition cdvdman.c:2075
int sceCdStStart(u32 lbn, sceCdRMode *mode)
Definition cdi.c:202
@ SCECdSpinX1
@ SCECdSpinX2
@ SCECdSpinNm2
@ SCECdSpinMax
@ SCECdSpinStm
@ SCECdSpinNom
@ SCECdSpinMx
@ SCECdSpinX12
@ SCECdSpinX4
int sceCdBootCertify(const u8 *romname)
int sceCdChgSys(u32 arg1)
int sceCdReadConfig(void *buffer, u32 *result)
int sceCdMV(u8 *buffer, u32 *status)
Definition cdvdman.c:7395
@ SCECdTrayCheck
@ SCECdTrayOpen
@ SCECdTrayClose
int sceCdStStat(void)
Definition cdi.c:209
void(* sceCdCBFunc)(int reason)
int sceCdWriteNVM(u32 address, u16 data, u8 *result)
int sceCdReadFull(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
int sceCdDecSet(unsigned char enable_xor, unsigned char enable_shift, unsigned char shiftval)
Definition cdvdman.c:8477
int sceCdBuzzerCtl(u32 *result)
int sceCdRI(u8 *buffer, u32 *result)
Definition cdvdman.c:7277
@ SCECdNODISC
@ SCECdIllegalMedia
@ SCECdPSCDDA
@ SCECdPSCD
@ SCECdDETCT
@ SCECdDVDV
@ SCECdDVDVR
@ SCECdPS2DVD
@ SCECdCDDA
@ SCECdPS2CDDA
@ SCECdPS2CD
@ SCECdErEOM
@ SCECdErIPI
@ SCECdErREAD
@ SCECdErNO
@ SCECdErABRT
@ SCECdErREADCF
@ SCECdErREADCFR
@ SCECdErNORDY
@ SCECdErTRMOPN
@ SCECdErCUD
@ SCECdErFAIL
@ SCECdErPRM
int sceCdNoticeGameStart(u8 arg1, u32 *result)
int sceCdReadWakeUpTime(sceCdCLOCK *clock, u16 *userdata, u32 *wakeupreason, int *flags)
int sceCdForbidDVDP(u32 *result)
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:6088
int sceCdWriteWakeUpTime(const sceCdCLOCK *clock, u16 userdata, int flags)
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:6862
int sceCdStop(void)
Definition cdi.c:157
int sceCdReadChain(sceCdRChain *tag, sceCdRMode *mode)
Definition cdvdman.c:7047
int sceCdOpenConfig(int block, int mode, int NumBlocks, u32 *status)
int sceCdTrayReq(int param, u32 *traychk)
Definition cdi.c:162
int sceCdSetLEDsMode(u32 param, u32 *result)
int sceCdWriteClock(sceCdCLOCK *clock)
int sceCdWriteRegionParams(u8 arg1, u32 *arg2, u8 *arg3, u32 *result)
int sceCdBlueLEDCtl(u8 control, u32 *result)
int sceCdCtrlADout(int mode, u32 *status)
Definition cdvdman.c:7601
@ SCECdStatSpin
@ SCECdStatPause
@ SCECdStatShellOpen
@ SCECdStatStop
@ SCECdEXIT
@ SCECdINIT
Definition cdvdman.c:43
Definition cdvdman.c:76
#define EA_MULTI
Definition thevent.h:35