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 *arg), void *arg);
197static int vCancelAlarm(unsigned int (*alarm_cb)(void *arg), 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 val);
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 val);
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 unsigned int sync_timeout_alarm_cb(void *userdata)
2070{
2071 const iop_sys_clock_t *sys_clock;
2072
2073 sys_clock = (const iop_sys_clock_t *)userdata;
2074 KPRINTF("Cdvd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
2075 return !sceCdBreak();
2076}
2077
2078int sceCdSetTimeout(int param, int timeout)
2079{
2080 if ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2081 {
2082 return 0;
2083 }
2084 switch ( param )
2085 {
2086 case 1:
2087 g_cdvdman_sync_timeout = timeout;
2088 return 1;
2089 case 2:
2090 g_cdvdman_stream_timeout = timeout;
2091 return 1;
2092 default:
2093 return 0;
2094 }
2095}
2096
2097int sceCdSync(int mode)
2098{
2099 iop_sys_clock_t sysclk;
2100 iop_event_info_t efinfo;
2101 u32 efbits;
2102
2103 VERBOSE_KPRINTF(1, "sceCdSync: Call mode %d Com %x\n", mode, (u8)g_cdvdman_istruct.m_cdvdman_command);
2104 switch ( mode )
2105 {
2106 case 0:
2107 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2108 {
2109 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2110 }
2111 break;
2112 case 1:
2113 return !!(!sceCdCheckCmd() || (g_cdvdman_istruct.m_read2_flag));
2114 case 3:
2115 sysclk.hi = 0;
2116 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
2117 vSetAlarm(&sysclk, sync_timeout_alarm_cb, &sysclk);
2118 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2119 {
2120 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2121 }
2122 vCancelAlarm(sync_timeout_alarm_cb, &sysclk);
2123 break;
2124 case 4:
2125 sysclk.hi = 0;
2126 sysclk.lo = 0x41EB0000;
2127 vSetAlarm(&sysclk, sync_timeout_alarm_cb, &sysclk);
2128 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2129 {
2130 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2131 }
2132 vCancelAlarm(sync_timeout_alarm_cb, &sysclk);
2133 break;
2134 case 5:
2135 while ( !sceCdCheckCmd() )
2136 {
2137 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2138 }
2139 break;
2140 case 6:
2141 sysclk.hi = 0;
2142 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
2143 vSetAlarm(&sysclk, sync_timeout_alarm_cb, &sysclk);
2144 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2145 {
2146 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2147 }
2148 vCancelAlarm(sync_timeout_alarm_cb, &sysclk);
2149 break;
2150 case 16:
2151 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2152 || g_cdvdman_istruct.m_stream_flag )
2153 {
2154 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2155 if ( g_cdvdman_ee_rpc_fno )
2156 {
2157 DelayThread(8000);
2158 }
2159 }
2160 break;
2161 case 17:
2162 return !!(
2163 !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2164 || (g_cdvdman_istruct.m_stream_flag));
2165 case 32:
2166 WaitEventFlag(g_cdvdman_intr_evfid, 0x21, WEF_OR, &efbits);
2167 ReferEventFlagStatus(g_cdvdman_intr_evfid, &efinfo);
2168 if ( !(efinfo.currBits & 0x20) )
2169 {
2170 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
2171 {
2172 SetEventFlag(g_cdvdman_intr_evfid, 0x20);
2173 }
2174 else
2175 {
2176 WaitEventFlag(g_cdvdman_intr_evfid, 0x20, WEF_AND, &efbits);
2177 }
2178 }
2179 break;
2180 default:
2181 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2182 {
2183 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2184 }
2185 break;
2186 }
2187 VERBOSE_KPRINTF(
2188 1,
2189 "sceCdSync: Command= %d Error= %d\n",
2190 (u8)g_cdvdman_istruct.m_cdvdman_command,
2191 (u8)g_cdvdman_istruct.m_last_error);
2192 return 0;
2193}
2194
2195int sceCdSpinCtrlIOP(u32 speed)
2196{
2197 VERBOSE_KPRINTF(1, "sceCdSpinCtrlIOP speed= %d\n", speed);
2198 g_cdvdman_spinctl = speed;
2199 return 1;
2200}
2201
2202int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
2203{
2204 unsigned int i;
2205 int search_res;
2206 u32 efbits;
2207
2208 if ( PollEventFlag(g_sfile_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
2209 {
2210 return 0;
2211 }
2212 for ( i = 0; i < ((sizeof(g_cdvdman_sfname) / sizeof(g_cdvdman_sfname[0])) - 1) && path[i]; i += 1 )
2213 {
2214 g_cdvdman_sfname[i] = path[i];
2215 }
2216 g_cdvdman_sfname[i] = 0;
2217 g_cdvdman_srchspd = 1;
2218 search_res = CdSearchFileInner((cdvdman_filetbl_entry_t *)fp, g_cdvdman_sfname, layer);
2219 vSetEventFlag(g_sfile_evfid, 1);
2220 return search_res;
2221}
2222
2223int sceCdSearchFile(sceCdlFILE *file, const char *name)
2224{
2225 return sceCdLayerSearchFile(file, name, 0);
2226}
2227
2228int sceCdGetToc(u8 *toc)
2229{
2230 return cdvdman_gettoc(toc);
2231}
2232
2233int sceCdDiskReady(int mode)
2234{
2235 u32 efbits;
2236 USE_DEV5_MMIO_HWPORT();
2237
2238 efbits = 0;
2239 // The following Kprintf was modified for ioprp300x
2240 VERBOSE_KPRINTF(1, "DISK READY call from iop %d\n", mode);
2241#ifdef CDVD_VARIANT_XOSD
2242 if ( g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1 )
2243 {
2244 return mode == 8 ? -1 : 6;
2245 }
2246 switch ( get_disk_type_ex() )
2247 {
2248 case SCECdNODISC:
2249 case 257:
2250 return 2;
2251 default:
2252 break;
2253 }
2254#endif
2255 switch ( mode )
2256 {
2257 case 0:
2258 VERBOSE_KPRINTF(1, "Wait Drive Ready %x\n", dev5_mmio_hwport->m_dev5_reg_005);
2259 while ( g_cdvdman_istruct.m_read2_flag )
2260 {
2261 // The following call to sceCdGetDiskType was inlined
2262#ifdef CDVD_VARIANT_XOSD
2263 switch ( get_disk_type_ex() )
2264#else
2265 switch ( sceCdGetDiskType() )
2266#endif
2267 {
2268 case SCECdDETCT:
2269 case SCECdDETCTCD:
2270 case SCECdDETCTDVDS:
2271 case SCECdDETCTDVDD:
2272 while ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) != 0x40 )
2273 {
2274 vDelayThread(2000);
2275 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2276#ifdef CDVD_VARIANT_XOSD
2277 if ( !get_disk_type_ex() )
2278 {
2279 return 2;
2280 }
2281#endif
2282 }
2283 continue;
2284 default:
2285 break;
2286 }
2287 break;
2288 }
2289 // The following Kprintf was added for ioprp300x
2290 VERBOSE_KPRINTF(1, "Wait Exit\n");
2291 return 2;
2292 case 8:
2293 return (u8)dev5_mmio_hwport->m_dev5_reg_005;
2294 case 1:
2295 default:
2296 if ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag )
2297 {
2298 return 2;
2299 }
2300 VERBOSE_KPRINTF(1, "Drive Not Ready\n");
2301 return 6;
2302 }
2303}
2304
2305int sceCdGetDiskType(void)
2306{
2307#ifdef CDVD_VARIANT_XOSD
2308 int cdvd_register;
2309
2310 VERBOSE_KPRINTF(1, "sceCdGetDiskType Call\n");
2311 cdvd_register = get_cdvd_register(0x0F);
2312 VERBOSE_KPRINTF(1, "sceCdGetDiskType 0x%02x\n", cdvd_register);
2313 return cdvd_register;
2314#else
2315 USE_DEV5_MMIO_HWPORT();
2316
2317 return (u8)dev5_mmio_hwport->m_dev5_reg_00F;
2318#endif
2319}
2320
2321#ifdef CDVD_VARIANT_XOSD
2322static int get_disk_type_ex(void)
2323{
2324 int IntrContext;
2325 int retval;
2326 int state;
2327 USE_DEV5_MMIO_HWPORT();
2328
2329 IntrContext = QueryIntrContext();
2330 if ( IntrContext )
2331 {
2332 CpuSuspendIntr(&state);
2333 }
2334 retval = (g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1) ? 257 : dev5_mmio_hwport->m_dev5_reg_00F;
2335 if ( IntrContext )
2336 {
2337 CpuResumeIntr(state);
2338 }
2339 return retval;
2340}
2341#endif
2342
2343#ifdef CDVD_VARIANT_XOSD
2344int sceCdGetWakeUpReason(void)
2345{
2346 int wakeup_reason_reg;
2347
2348 VERBOSE_KPRINTF(1, "sceCdGetWakeUpReason Call\n");
2349 wakeup_reason_reg = get_cdvd_register(0x15);
2350 if ( wakeup_reason_reg != -1 )
2351 {
2352 wakeup_reason_reg &= 0xF;
2353 }
2354 VERBOSE_KPRINTF(1, "sceCdGetWakeUpReason 0x%02x\n", wakeup_reason_reg);
2355 return wakeup_reason_reg;
2356}
2357#endif
2358
2359int sceCdStatus(void)
2360{
2361 int reg_00A_tmp;
2362#ifndef CDVD_VARIANT_XOSD
2363 u32 status_tmp;
2364#endif
2365#ifndef CDVD_VARIANT_XOSD
2366 USE_DEV5_MMIO_HWPORT();
2367#endif
2368
2369#ifdef CDVD_VARIANT_XOSD
2370 reg_00A_tmp = get_cdvd_register(0x0A);
2371#else
2372 reg_00A_tmp = dev5_mmio_hwport->m_dev5_reg_00A;
2373#endif
2374#ifndef CDVD_VARIANT_XOSD
2375 // The following call to sceCdGetDiskType was inlined
2376 if ( sceCdGetDiskType() == SCECdNODISC )
2377 {
2378 u8 rdata_tmp;
2379
2380 if ( !g_cdvdman_istruct.m_tray_is_open && cdvdman_scmd_sender_03_30(&rdata_tmp, &status_tmp) == 1 && !status_tmp )
2381 {
2382 reg_00A_tmp &= ~SCECdStatShellOpen;
2383 if ( (rdata_tmp & 8) )
2384 {
2385 reg_00A_tmp |= SCECdStatShellOpen;
2386 }
2387 }
2388 if ( (reg_00A_tmp & 0x1E) )
2389 {
2390 reg_00A_tmp = SCECdStatStop;
2391 }
2392 }
2393#endif
2394 if ( g_cdvdman_istruct.m_use_toc )
2395 {
2396 reg_00A_tmp &= ~SCECdStatShellOpen;
2397 }
2398 if ( g_cdvdman_istruct.m_power_flag )
2399 {
2400 return -1;
2401 }
2402 return reg_00A_tmp;
2403}
2404
2405#ifdef CDVD_VARIANT_OSD
2406int sceCdStatus2(void)
2407{
2408 USE_DEV5_MMIO_HWPORT();
2409
2410 return !g_cdvdman_istruct.m_power_flag ? (u8)dev5_mmio_hwport->m_dev5_reg_00A : -1;
2411}
2412#endif
2413
2415{
2416 p->sector = 16 * ((i + 150) % 75 / 10) + (i + 150) % 75 % 10;
2417 p->second = 16 * ((i + 150) / 75 % 60 / 10) + (i + 150) / 75 % 60 % 10;
2418 p->minute = 16 * ((i + 150) / 75 / 60 / 10) + (i + 150) / 75 / 60 % 10;
2419 return p;
2420}
2421
2422// cppcheck-suppress constParameterPointer
2424{
2425 return 75 * (60 * (10 * (p->minute >> 4) + (p->minute & 0xF)) + 10 * (p->second >> 4) + (p->second & 0xF))
2426 + 10 * (p->sector >> 4) + (p->sector & 0xF) - 150;
2427}
2428
2429#ifdef CDVD_VARIANT_DNAS
2430static int read_id_from_rom(int mode, int *buf)
2431{
2432 int chksumint;
2433 unsigned int i;
2434 unsigned int j;
2435 int idinfo[0x20];
2436 int chksumstk;
2437
2438 chksumint = 0;
2439 chksumstk = 0;
2440 for ( i = 0; i < (sizeof(idinfo) / sizeof(idinfo[0])); i += 1 )
2441 {
2442 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2443 {
2444 ((char *)&idinfo)[(i * 4) + j] = ((char *)0xBFBF0000)[(i * 4) + j];
2445 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2446 }
2447 chksumint += chksumstk;
2448 }
2449 for ( ; i < 0x4000; i += 1 )
2450 {
2451 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2452 {
2453 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2454 }
2455 chksumint += chksumstk;
2456 }
2457 if ( chksumint )
2458 {
2459 KPRINTF("# checksum error %d\n", chksumint);
2460 return 0;
2461 }
2462 if ( mode )
2463 {
2464 *buf = idinfo[11];
2465 }
2466 else
2467 {
2468 *buf = idinfo[2];
2469 buf[1] = idinfo[3];
2470 }
2471 return 1;
2472}
2473
2474static int query_boot_mode_6_nonzero(void)
2475{
2476 int *BootMode;
2477
2478 BootMode = QueryBootMode(6);
2479 return !(!BootMode || (*(u16 *)BootMode & 0xFFFC) != 0x60);
2480}
2481
2482static int query_boot_mode_6_zero(void)
2483{
2484 return !QueryBootMode(6);
2485}
2486
2487static int cdvdman_readID(int mode, int *buf)
2488{
2489 u8 id_val[8];
2490 iop_sys_clock_t sysclk;
2491 u32 id_result;
2492
2493 id_result = -1;
2494 if ( query_boot_mode_6_nonzero() )
2495 {
2496 if ( read_id_from_rom(mode, buf) && mode == 1 )
2497 {
2498 if ( *buf == -1 )
2499 {
2500 *buf = 0x1A0002;
2501 }
2502 return 1;
2503 }
2504 return 0;
2505 }
2506 else
2507 {
2508 if ( query_boot_mode_6_zero() )
2509 {
2510 if ( !sceCdRI(id_val, &id_result) || id_result )
2511 {
2512 return 0;
2513 }
2514 }
2515 else
2516 {
2517 if ( !g_readid_systemtime.lo && !g_readid_systemtime.hi )
2518 {
2519 GetSystemTime(&sysclk);
2520 g_readid_systemtime = sysclk;
2521 }
2522 *(iop_sys_clock_t *)id_val = g_readid_systemtime;
2523 }
2524 if ( mode )
2525 {
2526 *buf = *(u32 *)id_val >> 8;
2527 }
2528 else
2529 {
2530 *buf = id_val[0] | 0x8004600;
2531 buf[1] = *(u32 *)&id_val[4];
2532 }
2533 return 1;
2534 }
2535}
2536
2537int sceCdReadGUID(u64 *guid)
2538{
2539 return cdvdman_readID(0, (int *)guid);
2540}
2541
2542int sceCdReadModelID(unsigned int *id)
2543{
2544 return cdvdman_readID(1, (int *)id);
2545}
2546#endif
2547
2548int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
2549{
2550 cdrom_stm_devctl_t devctl_req;
2551 int buf;
2552
2553 // The following Kprintf was added for ioprp300x
2554 VERBOSE_KPRINTF(1, "sceCdStInit call IOP\n");
2555 memset(&devctl_req, 0, sizeof(devctl_req));
2556 devctl_req.m_cmdid = 5;
2557 devctl_req.m_posszarg1 = bufmax;
2558 devctl_req.m_posszarg2 = bankmax;
2559 devctl_req.m_buffer = buffer;
2560 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2561}
2562
2563// cppcheck-suppress constParameterPointer
2564int sceCdStStart(u32 lbn, sceCdRMode *mode)
2565{
2566 cdrom_stm_devctl_t devctl_req;
2567 int buf;
2568
2569 // The following Kprintf was added for ioprp300x
2570 VERBOSE_KPRINTF(1, "sceCdStStart call IOP\n");
2571 memset(&devctl_req, 0, sizeof(devctl_req));
2572 devctl_req.m_rmode.datapattern = mode->datapattern;
2573 devctl_req.m_rmode.spindlctrl = mode->spindlctrl;
2574 devctl_req.m_cmdid = 1;
2575 devctl_req.m_posszarg1 = lbn;
2576 devctl_req.m_rmode.trycount = mode->trycount;
2577 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2578}
2579
2580int sceCdStSeekF(unsigned int lsn)
2581{
2582 cdrom_stm_devctl_t devctl_req;
2583 int buf;
2584
2585 // The following Kprintf was added for ioprp300x
2586 VERBOSE_KPRINTF(1, "sceCdStSeekF call IOP\n");
2587 memset(&devctl_req, 0, sizeof(devctl_req));
2588 devctl_req.m_cmdid = 9;
2589 devctl_req.m_posszarg1 = lsn;
2590 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2591}
2592
2593int sceCdStSeek(u32 lbn)
2594{
2595 cdrom_stm_devctl_t devctl_req;
2596 int buf;
2597
2598 // The following Kprintf was added for ioprp300x
2599 VERBOSE_KPRINTF(1, "sceCdStSeek call IOP\n");
2600 memset(&devctl_req, 0, sizeof(devctl_req));
2601 devctl_req.m_posszarg1 = lbn;
2602 devctl_req.m_cmdid = 4;
2603 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2604}
2605
2606int sceCdStStop(void)
2607{
2608 cdrom_stm_devctl_t devctl_req;
2609 int buf;
2610
2611 // The following Kprintf was added for ioprp300x
2612 VERBOSE_KPRINTF(1, "sceCdStStop call IOP\n");
2613 memset(&devctl_req, 0, sizeof(devctl_req));
2614 devctl_req.m_cmdid = 3;
2615 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2616}
2617
2618int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
2619{
2620 cdrom_stm_devctl_t devctl_req;
2621 int buf;
2622
2623 (void)mode;
2624
2625 // The following Kprintf was added for ioprp300x
2626 VERBOSE_KPRINTF(1, "sceCdStRead call IOP\n");
2627 memset(&devctl_req, 0, sizeof(devctl_req));
2628 devctl_req.m_cmdid = 1;
2629 devctl_req.m_posszarg2 = sectors;
2630 devctl_req.m_buffer = buffer;
2631 if ( devctl("cdrom_stm0:", 0x4394, &devctl_req, sizeof(devctl_req), &buf, 4) < 0 )
2632 {
2633 buf = 0;
2634 }
2635 *error = devctl_req.m_error;
2636 return buf;
2637}
2638
2639int sceCdStPause(void)
2640{
2641 cdrom_stm_devctl_t devctl_req;
2642 int buf;
2643
2644 // The following Kprintf was added for ioprp300x
2645 VERBOSE_KPRINTF(1, "sceCdStPause call IOP\n");
2646 memset(&devctl_req, 0, sizeof(devctl_req));
2647 devctl_req.m_cmdid = 7;
2648 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2649}
2650
2651int sceCdStResume(void)
2652{
2653 cdrom_stm_devctl_t devctl_req;
2654 int buf;
2655
2656 // The following Kprintf was added for ioprp300x
2657 VERBOSE_KPRINTF(1, "sceCdStResume call IOP\n");
2658 memset(&devctl_req, 0, sizeof(devctl_req));
2659 devctl_req.m_cmdid = 8;
2660 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2661}
2662
2663int sceCdStStat(void)
2664{
2665 cdrom_stm_devctl_t devctl_req;
2666 int buf;
2667
2668 // The following Kprintf was added for ioprp300x
2669 VERBOSE_KPRINTF(1, "sceCdStStat call IOP\n");
2670 memset(&devctl_req, 0, sizeof(devctl_req));
2671 devctl_req.m_cmdid = 6;
2672 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2673}
2674
2675static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer)
2676{
2677 int parent_level;
2678 int i;
2679 unsigned int j;
2680 char name_buf[32];
2681
2682 VERBOSE_PRINTF(1, "CdSearchFile: start name= %s layer= %d\n", name, layer);
2683 if ( g_cdvdman_fs_layer != layer )
2684 {
2685 g_cdvdman_fs_cache = 0;
2686 }
2687 if ( !cdvdman_mediactl(0) && g_cdvdman_fs_cache )
2688 {
2689 VERBOSE_KPRINTF(1, "CdSearchFile: cache dir data used\n");
2690 }
2691 else
2692 {
2693 VERBOSE_PRINTF(1, "CdSearchFile Topen= %s\n", name);
2694 if ( !CD_newmedia(layer) )
2695 {
2696 g_cdvdman_fs_cache = 0;
2697 return 0;
2698 }
2699 g_cdvdman_fs_cache = 1;
2700 }
2701 if ( *name != '\\' )
2702 {
2703 return 0;
2704 }
2705 name_buf[0] = 0;
2706 parent_level = 1;
2707 j = 0;
2708 for ( i = 0; i < 8 && name[i]; i += 1 )
2709 {
2710 for ( j = 0; name[i + j] != '\\'; j += 1 )
2711 {
2712 name_buf[j] = name[i + j];
2713 }
2714 name_buf[j] = 0;
2715 parent_level = cdvdman_finddir(parent_level, name_buf);
2716 if ( parent_level == -1 )
2717 {
2718 name_buf[0] = 0;
2719 break;
2720 }
2721 }
2722 if ( i >= 8 )
2723 {
2724 VERBOSE_PRINTF(1, "%s: path level (%d) error\n", name, i);
2725 return 0;
2726 }
2727 if ( !name_buf[0] )
2728 {
2729 VERBOSE_PRINTF(1, "%s: dir was not found\n", name);
2730 return 0;
2731 }
2732 name_buf[j] = 0;
2733 if ( !CD_cachefile(parent_level, layer) )
2734 {
2735 VERBOSE_PRINTF(1, "CdSearchFile: disc error\n");
2736 return 0;
2737 }
2738 VERBOSE_PRINTF(2, "CdSearchFile: searching %s...\n", name_buf);
2739 for ( j = 0;
2740 j < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) && g_cdvdman_filetbl[j].m_file_struct.name[0];
2741 j += 1 )
2742 {
2743 VERBOSE_PRINTF(1, "%d %s %s\n", (int)j, g_cdvdman_filetbl[j].m_file_struct.name, name_buf);
2744 if ( cdvdman_cmpname(g_cdvdman_filetbl[j].m_file_struct.name, name_buf) )
2745 {
2746 VERBOSE_PRINTF(2, "%s:\t found\n", name_buf);
2747 // The following memcpy was inlined
2748 memcpy(fp, &g_cdvdman_filetbl[j], sizeof(cdvdman_filetbl_entry_t));
2749 fp->m_file_struct.lsn += layer ? g_cdvdman_fs_base2 : 0;
2750 return 1;
2751 }
2752 }
2753 VERBOSE_PRINTF(1, "%s: not found\n", name_buf);
2754 return 0;
2755}
2756
2757static int sceCdSearchDir(char *dirname, int layer)
2758{
2759 sceCdlFILE fp;
2760
2761 VERBOSE_PRINTF(1, "_sceCdSearchDir: dir name %s layer %d\n", dirname, layer);
2762 return sceCdLayerSearchFile(&fp, dirname, layer) ? g_cdvdman_fs_cdsec : SCECdErREADCFR;
2763}
2764
2765static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer)
2766{
2767 VERBOSE_PRINTF(1, "_sceCdReadDir: current= %d dsec= %d layer= %d\n", g_cdvdman_fs_cdsec, dsec, layer);
2768 if ( g_cdvdman_fs_cdsec != dsec || g_cdvdman_fs_layer != layer )
2769 {
2770 if ( g_cdvdman_fs_layer != layer )
2771 {
2772 if ( !CD_newmedia(layer) )
2773 {
2774 return -ENOENT;
2775 }
2776 g_cdvdman_fs_cache = 1;
2777 }
2778 if ( !CD_cachefile(dsec, layer) )
2779 {
2780 return -ENOENT;
2781 }
2782 }
2783 if ( g_cdvdman_filetbl[index].m_file_struct.name[0] )
2784 {
2785 VERBOSE_PRINTF(1, "%s:\t found dir_point %d\n", g_cdvdman_filetbl[index].m_file_struct.name, index);
2786 // The following memcpy was inlined
2787 memcpy(fp, &g_cdvdman_filetbl[index], sizeof(cdvdman_filetbl_entry_t));
2788 return 1;
2789 }
2790 return 0;
2791}
2792
2793static int cdvdman_cmpname(const char *p, const char *q)
2794{
2795 return !strncmp(p, q, 12);
2796}
2797
2798static int CD_newmedia(int arg)
2799{
2800 unsigned int DiskType;
2801 unsigned int i;
2802 iso9660_path_t *path_cur;
2803 int state;
2804 int ptsector;
2805
2806 ptsector = 0;
2807#ifdef CDVD_VARIANT_XOSD
2808 DiskType = get_disk_type_ex();
2809#else
2810 DiskType = sceCdGetDiskType();
2811#endif
2812 switch ( DiskType )
2813 {
2814 case SCECdPSCD:
2815 case SCECdPSCDDA:
2816 case SCECdPS2CD:
2817 case SCECdPS2CDDA:
2818 case SCECdPS2DVD:
2819 case SCECdDVDVR:
2820 case SCECdDVDV:
2821 case SCECdIllegalMedia:
2822 break;
2823 default:
2824 VERBOSE_PRINTF(1, "CD_newmedia: Illegal disc media type =%d\n", (int)DiskType);
2825 return 0;
2826 }
2827 g_cdvdman_fs_base2 = 0;
2828 if ( DiskType == SCECdPS2DVD )
2829 {
2830 if ( !DvdDual_infochk() )
2831 {
2832 VERBOSE_PRINTF(1, "CD_newmedia: Get DvdDual_infochk fail\n");
2833 return 0;
2834 }
2835 g_cdvdman_fs_base2 = arg ? g_cdvdman_istruct.m_layer_1_lsn : 0;
2836 }
2837 if ( disc_read(1, g_cdvdman_fs_base2 + 0x10, g_cdvdman_fs_rbuf, arg) != 1 )
2838 {
2839 VERBOSE_PRINTF(1, "CD_newmedia: Read error in disc_read(PVD)\n");
2840 return 0;
2841 }
2842 CpuSuspendIntr(&state);
2843 for ( i = 0; i < g_cdvdman_pathtblsize; i += 1 )
2844 {
2845 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
2846 g_cdvdman_pathtbl[i].m_layer = 0;
2847 g_cdvdman_pathtbl[i].m_nsec = 0;
2848 g_cdvdman_pathtbl[i].m_lsn = 0;
2849 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
2850 }
2851 g_cache_count = 0;
2852 g_cache_table = 0;
2853 g_cache_path_size = 0;
2854 CpuResumeIntr(state);
2855 if ( strncmp((char *)((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_id, "CD001", 5) )
2856 {
2857 VERBOSE_PRINTF(1, "CD_newmedia: Disc format error in cd_read(PVD)\n");
2858 return 0;
2859 }
2860 switch ( DiskType )
2861 {
2862 case SCECdPSCD:
2863 case SCECdPSCDDA:
2864 case SCECdPS2CD:
2865 case SCECdPS2CDDA:
2866 VERBOSE_PRINTF(1, "CD_newmedia: CD Read mode\n");
2867 ptsector = *(u32 *)(((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_type_l_path_table);
2868 break;
2869 case SCECdPS2DVD:
2870 case SCECdDVDVR:
2871 case SCECdDVDV:
2872 VERBOSE_PRINTF(1, "CD_newmedia: DVD Read mode\n");
2873 ptsector = 257;
2874 break;
2875 }
2876 if ( disc_read(1, g_cdvdman_fs_base2 + ptsector, g_cdvdman_fs_rbuf, arg) != 1 )
2877 {
2878 VERBOSE_PRINTF(1, "CD_newmedia: Read error (PT:%08x)\n", ptsector);
2879 return 0;
2880 }
2881 VERBOSE_PRINTF(2, "CD_newmedia: sarching dir..\n");
2882 for ( i = 0, path_cur = (iso9660_path_t *)g_cdvdman_fs_rbuf;
2883 i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0]))
2884 && path_cur < (iso9660_path_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)] && path_cur->m_name_len[0];
2885 i += 1,
2886 path_cur = (iso9660_path_t *)(((char *)path_cur) + path_cur->m_name_len[0] + (path_cur->m_name_len[0] & 1)
2887 + sizeof(iso9660_path_t)) )
2888 {
2889 memcpy(&g_cdvdman_dirtbl[i].m_extent, path_cur->m_extent, sizeof(path_cur->m_extent));
2890 g_cdvdman_dirtbl[i].m_number = i;
2891 memcpy(&g_cdvdman_dirtbl[i].m_parent, path_cur->m_parent, sizeof(path_cur->m_parent));
2892 memcpy(g_cdvdman_dirtbl[i].m_name, path_cur->m_name, path_cur->m_name_len[0]);
2893 g_cdvdman_dirtbl[i].m_name[path_cur->m_name_len[0]] = 0;
2894 VERBOSE_PRINTF(
2895 2,
2896 "\t%08x,%04x,%04x,%s\n",
2897 g_cdvdman_dirtbl[i].m_extent,
2898 g_cdvdman_dirtbl[i].m_number,
2899 g_cdvdman_dirtbl[i].m_parent,
2900 g_cdvdman_dirtbl[i].m_name);
2901 }
2902 if ( i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) )
2903 {
2904 g_cdvdman_dirtbl[i].m_parent = 0;
2905 }
2906 g_cdvdman_fs_cdsec = 0;
2907 g_cdvdman_fs_layer = arg;
2908 VERBOSE_PRINTF(2, "CD_newmedia: %d dir entries found\n", (int)i);
2909 return 1;
2910}
2911
2912static int cdvdman_finddir(int target_parent, const char *target_name)
2913{
2914 unsigned int i;
2915
2916 for ( i = 0; i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) && g_cdvdman_dirtbl[i].m_parent; i += 1 )
2917 {
2918 if ( g_cdvdman_dirtbl[i].m_parent == target_parent && !strcmp(target_name, g_cdvdman_dirtbl[i].m_name) )
2919 {
2920 return i + 1;
2921 }
2922 }
2923 return -1;
2924}
2925
2926static int CD_cachefile(int dsec, int layer)
2927{
2928 iso9660_dirent_t *dirent_cur;
2929 unsigned int i;
2930
2931 if ( dsec == g_cdvdman_fs_cdsec )
2932 {
2933 return 1;
2934 }
2935 if (
2936 disc_read(1, g_cdvdman_dirtbl[dsec - 1].m_extent + (layer ? g_cdvdman_fs_base2 : 0), g_cdvdman_fs_rbuf, layer)
2937 != 1 )
2938 {
2939 VERBOSE_PRINTF(1, "CD_cachefile: dir not found\n");
2940 g_cdvdman_fs_cdsec = 0;
2941 return 0;
2942 }
2943 VERBOSE_PRINTF(2, "CD_cachefile: searching...\n");
2944 for ( i = 0, dirent_cur = (iso9660_dirent_t *)g_cdvdman_fs_rbuf;
2945 i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0]))
2946 && dirent_cur < (iso9660_dirent_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)];
2947 i += 1, dirent_cur = (iso9660_dirent_t *)((char *)dirent_cur + dirent_cur->m_length[0]) )
2948 {
2949 int file_year;
2950
2951 if ( !dirent_cur->m_length[0] )
2952 {
2953 break;
2954 }
2955 memcpy(
2956 &g_cdvdman_filetbl[i].m_file_struct.lsn, dirent_cur->m_extent, sizeof(g_cdvdman_filetbl[i].m_file_struct.lsn));
2957 memcpy(
2958 &g_cdvdman_filetbl[i].m_file_struct.size, dirent_cur->m_size, sizeof(g_cdvdman_filetbl[i].m_file_struct.size));
2959 file_year = dirent_cur->m_date[0] + 1900;
2960 g_cdvdman_filetbl[i].m_file_struct.date[7] = file_year >> 8;
2961 g_cdvdman_filetbl[i].m_file_struct.date[6] = file_year;
2962 g_cdvdman_filetbl[i].m_file_struct.date[5] = dirent_cur->m_date[1];
2963 g_cdvdman_filetbl[i].m_file_struct.date[4] = dirent_cur->m_date[2];
2964 g_cdvdman_filetbl[i].m_file_struct.date[3] = dirent_cur->m_date[3];
2965 g_cdvdman_filetbl[i].m_file_struct.date[2] = dirent_cur->m_date[4];
2966 g_cdvdman_filetbl[i].m_file_struct.date[1] = dirent_cur->m_date[5];
2967 g_cdvdman_filetbl[i].m_flags = dirent_cur->m_flags[0];
2968 switch ( i )
2969 {
2970 case 0:
2971 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, ".");
2972 break;
2973 case 1:
2974 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, "..");
2975 break;
2976 default:
2977 memcpy(g_cdvdman_filetbl[i].m_file_struct.name, dirent_cur->m_name, dirent_cur->m_name_len[0]);
2978 g_cdvdman_filetbl[i].m_file_struct.name[dirent_cur->m_name_len[0]] = 0;
2979 break;
2980 }
2981 VERBOSE_PRINTF(
2982 2,
2983 "\t lsn %d size %d name:%d:%s %d/%d/%d %d:%d:%d\n",
2984 (int)(g_cdvdman_filetbl[i].m_file_struct.lsn),
2985 (int)(g_cdvdman_filetbl[i].m_file_struct.size),
2986 dirent_cur->m_name_len[0],
2987 g_cdvdman_filetbl[i].m_file_struct.name,
2988 file_year,
2989 g_cdvdman_filetbl[i].m_file_struct.date[5],
2990 g_cdvdman_filetbl[i].m_file_struct.date[4],
2991 g_cdvdman_filetbl[i].m_file_struct.date[3],
2992 g_cdvdman_filetbl[i].m_file_struct.date[2],
2993 g_cdvdman_filetbl[i].m_file_struct.date[1]);
2994 }
2995 g_cdvdman_fs_cdsec = dsec;
2996 if ( i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) )
2997 {
2998 g_cdvdman_filetbl[i].m_file_struct.name[0] = 0;
2999 }
3000 VERBOSE_PRINTF(2, "CD_cachefile: %d files found\n", (int)i);
3001 return 1;
3002}
3003
3004static int disc_read(int size, int loc, void *buffer, int layer)
3005{
3006 int f;
3007 int i;
3008 sceCdRMode rmode;
3009 int has_success;
3010
3011 has_success = 1;
3012 f = 0;
3013 rmode.trycount = 16;
3014 VERBOSE_PRINTF(1, "cd_read:lsn= %d size= %d layer= %d\n", loc, size, layer);
3015 if ( cdvdman_l0check(layer) )
3016 {
3017 g_cdvdman_srchspd = 0;
3018 }
3019 switch ( g_cdvdman_srchspd )
3020 {
3021 case SCECdSpinX1:
3022 case SCECdSpinX2:
3023 case SCECdSpinX4:
3024 rmode.spindlctrl = g_cdvdman_srchspd;
3025 break;
3026 case SCECdSpinStm:
3027 case SCECdSpinNom:
3028 rmode.spindlctrl = !!g_cdvdman_srchspd;
3029 break;
3030 default:
3031 rmode.spindlctrl = SCECdSpinNom;
3032 break;
3033 }
3034 rmode.datapattern = SCECdSecS2048;
3035 if ( !g_cdvdman_pathtblflag )
3036 {
3037 has_success = 1;
3038 }
3039 if ( !has_success )
3040 {
3041 int pathcachecnt;
3042
3043 pathcachecnt = (g_cache_count < g_cdvdman_pathtblsize) ? g_cache_count : g_cdvdman_pathtblsize;
3044 for ( i = 0; i < pathcachecnt; i += 1 )
3045 {
3046 VERBOSE_KPRINTF(
3047 1,
3048 "Path table Cache Search lsn:%d:%d nsec:%d:%d layer%d:%d\n",
3049 g_cdvdman_pathtbl[i].m_lsn,
3050 loc,
3051 g_cdvdman_pathtbl[i].m_nsec,
3052 size,
3053 g_cdvdman_pathtbl[i].m_layer,
3054 layer);
3055 if (
3056 g_cdvdman_pathtbl[i].m_lsn == loc && g_cdvdman_pathtbl[i].m_nsec == (unsigned int)size
3057 && g_cdvdman_pathtbl[i].m_layer == layer )
3058 {
3059 break;
3060 }
3061 }
3062 if ( i != pathcachecnt )
3063 {
3064 VERBOSE_KPRINTF(1, "Path table Cache ON:%d\n", g_cdvdman_pathtbl[i].m_cache_path_sz);
3065 if ( lseek(g_cache_path_fd, g_cdvdman_pathtbl[i].m_cache_path_sz, 0) >= 0 )
3066 {
3067 read(g_cache_path_fd, buffer, size << 11);
3068 f = 1;
3069 g_cdvdman_pathtbl[i].m_cache_hit_count += 1;
3070 }
3071 has_success = 1;
3072 }
3073 if ( !has_success )
3074 {
3075 if ( !sceCdRE(loc, size, buffer, &rmode) )
3076 {
3077 return 0;
3078 }
3079 sceCdSync(3);
3080 }
3081 }
3082 if ( !has_success && sceCdGetError() != SCECdErNO )
3083 {
3084 int cache_path_sz;
3085
3086 if ( g_cache_count >= g_cdvdman_pathtblsize )
3087 {
3088 int cachetblo1;
3089 unsigned int cacheblo2;
3090
3091 g_cache_table += 1;
3092 if ( g_cache_table >= g_cdvdman_pathtblsize )
3093 {
3094 g_cache_table = 0;
3095 }
3096 cachetblo1 = g_cache_table;
3097 cacheblo2 = cachetblo1;
3098 for ( i = 0; (unsigned int)i < g_cache_count; i += 1 )
3099 {
3100 if ( cacheblo2 >= g_cdvdman_pathtblsize )
3101 {
3102 cacheblo2 = 0;
3103 }
3104 if (
3105 g_cdvdman_pathtbl[cacheblo2].m_nsec >= (unsigned int)size
3106 && g_cdvdman_pathtbl[cacheblo2].m_cache_hit_count
3107 < (unsigned int)g_cdvdman_pathtbl[cachetblo1].m_cache_hit_count )
3108 {
3109 cachetblo1 = cacheblo2;
3110 }
3111 cacheblo2 += 1;
3112 }
3113 cache_path_sz = g_cdvdman_pathtbl[cachetblo1].m_cache_path_sz;
3114 g_cache_table = cachetblo1;
3115 }
3116 else
3117 {
3118 cache_path_sz = g_cache_path_size;
3119 g_cache_table = g_cache_count;
3120 g_cache_count += 1;
3121 }
3122 if ( lseek(g_cache_path_fd, cache_path_sz, 0) >= 0 )
3123 {
3124 int ptbl_wcache_write_res;
3125
3126 ptbl_wcache_write_res = write(g_cache_path_fd, buffer, size << 11);
3127 if ( ptbl_wcache_write_res == size << 11 )
3128 {
3129 f = 1;
3130 g_cdvdman_pathtbl[g_cache_table].m_cache_path_sz = cache_path_sz;
3131 g_cdvdman_pathtbl[g_cache_table].m_lsn = loc;
3132 g_cdvdman_pathtbl[g_cache_table].m_nsec = size;
3133 g_cdvdman_pathtbl[g_cache_table].m_layer = layer;
3134 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
3135 g_cache_path_size += (g_cache_count < g_cdvdman_pathtblsize) ? ptbl_wcache_write_res : 0;
3136 }
3137 else
3138 {
3139 VERBOSE_KPRINTF(1, "Ptbl_WCache:write %d", ptbl_wcache_write_res);
3140 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
3141 g_cdvdman_pathtbl[g_cache_table].m_layer = 0;
3142 g_cdvdman_pathtbl[g_cache_table].m_nsec = 0;
3143 g_cdvdman_pathtbl[g_cache_table].m_lsn = 0;
3144 }
3145 }
3146 has_success = 1;
3147 }
3148 if ( has_success )
3149 {
3150 if ( f )
3151 {
3152 return size;
3153 }
3154 if ( !sceCdRE(loc, size, buffer, &rmode) )
3155 {
3156 return 0;
3157 }
3158 sceCdSync(3);
3159 if ( sceCdGetError() != SCECdErNO )
3160 {
3161 return size;
3162 }
3163 }
3164 VERBOSE_KPRINTF(1, "cd_read: error code %x\n", sceCdGetError());
3165 return 0;
3166}
3167
3168static int path_tbl_init(u32 blocks, char *fname, int action)
3169{
3170 int num;
3171 int v;
3172 char cachedir[512];
3173 int state;
3174 u32 blocksbs;
3175
3176 num = 0;
3177 v = 0;
3178 if ( action )
3179 {
3180 CpuSuspendIntr(&state);
3181 g_cdvdman_pathtbl = (cdvdman_pathtbl_t *)AllocSysMemory(ALLOC_LAST, sizeof(cdvdman_pathtbl_t) * blocks, 0);
3182 if ( !g_cdvdman_pathtbl )
3183 {
3184 CpuResumeIntr(state);
3185 g_cdvdman_pathtblflag = 0;
3186 return -ENOMEM;
3187 }
3188 CpuResumeIntr(state);
3189 sprintf(cachedir, "%sCache_Path", fname);
3190 v = open(cachedir, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
3191 if ( v >= 0 )
3192 {
3193 u32 i;
3194
3195 g_cache_path_fd = v;
3196 if ( !strncmp(cachedir, "pfs", 3) )
3197 {
3198 blocksbs = blocks << 11;
3199 ioctl2(g_cache_path_fd, PIOCALLOC, &blocksbs, sizeof(blocksbs), 0, 0);
3200 }
3201 for ( i = 0; i < blocks; i += 1 )
3202 {
3203 v = write(g_cache_path_fd, g_cdvdman_fs_rbuf, sizeof(g_cdvdman_fs_rbuf));
3204 if ( v < 0 )
3205 {
3206 break;
3207 }
3208 }
3209 if ( v >= 0 )
3210 {
3211 CpuSuspendIntr(&state);
3212 g_cdvdman_pathtblsize = blocks;
3213 for ( i = 0; i < blocks; i += 1 )
3214 {
3215 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
3216 g_cdvdman_pathtbl[i].m_layer = 0;
3217 g_cdvdman_pathtbl[i].m_nsec = 0;
3218 g_cdvdman_pathtbl[i].m_lsn = 0;
3219 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
3220 }
3221 g_cache_path_size = 0;
3222 g_cache_count = 0;
3223 g_cache_table = 0;
3224 g_cdvdman_pathtblflag = 1;
3225 CpuResumeIntr(state);
3226 return 0;
3227 }
3228 }
3229 }
3230 if ( g_cache_path_fd != -1 )
3231 {
3232 num = close(g_cache_path_fd);
3233 if ( num >= 0 )
3234 {
3235 if ( !strncmp(cachedir, "pfs", 3) )
3236 {
3237 num = remove(cachedir);
3238 }
3239 else if ( !strncmp(cachedir, "host", 4) )
3240 {
3241 num = 0;
3242 remove(cachedir);
3243 }
3244 }
3245 }
3246 CpuSuspendIntr(&state);
3247 g_cache_path_fd = -1;
3248 g_cache_count = 0;
3249 g_cache_table = 0;
3250 g_cache_path_size = 0;
3251 g_cdvdman_pathtblflag = 0;
3252 g_cdvdman_pathtblsize = 0;
3253 FreeSysMemory(g_cdvdman_pathtbl);
3254 g_cdvdman_pathtbl = 0;
3255 CpuResumeIntr(state);
3256 if ( v < 0 )
3257 {
3258 VERBOSE_KPRINTF(1, "path_tbl_init Error %d\n", v);
3259 }
3260 return (!action) ? num : v;
3261}
3262
3263// Unofficial: unused obfuscation code was removed
3264
3265// clang-format off
3266__asm__ (
3267 "\t" ".set push" "\n"
3268 "\t" ".set noat" "\n"
3269 "\t" ".set noreorder" "\n"
3270 "\t" ".global optimized_memcpy" "\n"
3271 "\t" "optimized_memcpy:" "\n"
3272 "\t" " srl $a3, $a2, 2" "\n"
3273 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3274 "\t" " or $a3, $a0, $a1" "\n"
3275 "\t" " andi $a3, $a3, 0x3" "\n"
3276 "\t" " bnez $a3, .Loptimized_memcpy_3" "\n"
3277 "\t" " nop" "\n"
3278 "\t" " srl $a3, $a2, 2" "\n"
3279 "\t" " addiu $at, $zero, 0xC" "\n"
3280 "\t" " div $zero, $a3, $at" "\n"
3281 "\t" " mflo $a3" "\n"
3282 "\t" " mfhi $v1" "\n"
3283 "\t" " beqz $v1, .Loptimized_memcpy_2" "\n"
3284 "\t" " nop" "\n"
3285 "\t" ".Loptimized_memcpy_1:" "\n"
3286 "\t" " lw $v0, 0x0($a1)" "\n"
3287 "\t" " addiu $v1, $v1, -0x1" "\n"
3288 "\t" " sw $v0, 0x0($a0)" "\n"
3289 "\t" " addiu $a1, $a1, 0x4" "\n"
3290 "\t" " bnez $v1, .Loptimized_memcpy_1" "\n"
3291 "\t" " addiu $a0, $a0, 0x4" "\n"
3292 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3293 "\t" " nop" "\n"
3294 "\t" ".Loptimized_memcpy_2:" "\n"
3295 "\t" " lw $v0, 0x0($a1)" "\n"
3296 "\t" " lw $v1, 0x4($a1)" "\n"
3297 "\t" " lw $t0, 0x8($a1)" "\n"
3298 "\t" " lw $t1, 0xC($a1)" "\n"
3299 "\t" " lw $t2, 0x10($a1)" "\n"
3300 "\t" " lw $t3, 0x14($a1)" "\n"
3301 "\t" " lw $t4, 0x18($a1)" "\n"
3302 "\t" " lw $t5, 0x1C($a1)" "\n"
3303 "\t" " lw $t6, 0x20($a1)" "\n"
3304 "\t" " lw $t7, 0x24($a1)" "\n"
3305 "\t" " lw $t8, 0x28($a1)" "\n"
3306 "\t" " lw $t9, 0x2C($a1)" "\n"
3307 "\t" " addiu $a3, $a3, -0x1" "\n"
3308 "\t" " sw $v0, 0x0($a0)" "\n"
3309 "\t" " sw $v1, 0x4($a0)" "\n"
3310 "\t" " sw $t0, 0x8($a0)" "\n"
3311 "\t" " sw $t1, 0xC($a0)" "\n"
3312 "\t" " sw $t2, 0x10($a0)" "\n"
3313 "\t" " sw $t3, 0x14($a0)" "\n"
3314 "\t" " sw $t4, 0x18($a0)" "\n"
3315 "\t" " sw $t5, 0x1C($a0)" "\n"
3316 "\t" " sw $t6, 0x20($a0)" "\n"
3317 "\t" " sw $t7, 0x24($a0)" "\n"
3318 "\t" " sw $t8, 0x28($a0)" "\n"
3319 "\t" " sw $t9, 0x2C($a0)" "\n"
3320 "\t" " addiu $a1, $a1, 0x30" "\n"
3321 "\t" " bnez $a3, .Loptimized_memcpy_2" "\n"
3322 "\t" " addiu $a0, $a0, 0x30" "\n"
3323 "\t" " j .Loptimized_memcpy_12" "\n"
3324 "\t" " nop" "\n"
3325 "\t" ".Loptimized_memcpy_3:" "\n"
3326 "\t" " andi $a3, $a0, 0x3" "\n"
3327 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3328 "\t" " andi $a3, $a1, 0x3" "\n"
3329 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3330 "\t" " nop" "\n"
3331 "\t" " srl $a3, $a2, 2" "\n"
3332 "\t" " addiu $at, $zero, 0xC" "\n"
3333 "\t" " div $zero, $a3, $at" "\n"
3334 "\t" " mflo $a3" "\n"
3335 "\t" " mfhi $v1" "\n"
3336 "\t" " beqz $v1, .Loptimized_memcpy_5" "\n"
3337 "\t" " nop" "\n"
3338 "\t" ".Loptimized_memcpy_4:" "\n"
3339 "\t" " lwl $v0, 0x3($a1)" "\n"
3340 "\t" " lwr $v0, 0x0($a1)" "\n"
3341 "\t" " addiu $v1, $v1, -0x1" "\n"
3342 "\t" " swl $v0, 0x3($a0)" "\n"
3343 "\t" " swr $v0, 0x0($a0)" "\n"
3344 "\t" " addiu $a1, $a1, 0x4" "\n"
3345 "\t" " bnez $v1, .Loptimized_memcpy_4" "\n"
3346 "\t" " addiu $a0, $a0, 0x4" "\n"
3347 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3348 "\t" " nop" "\n"
3349 "\t" ".Loptimized_memcpy_5:" "\n"
3350 "\t" " lwl $v0, 0x3($a1)" "\n"
3351 "\t" " lwr $v0, 0x0($a1)" "\n"
3352 "\t" " lwl $v1, 0x7($a1)" "\n"
3353 "\t" " lwr $v1, 0x4($a1)" "\n"
3354 "\t" " lwl $t0, 0xB($a1)" "\n"
3355 "\t" " lwr $t0, 0x8($a1)" "\n"
3356 "\t" " lwl $t1, 0xF($a1)" "\n"
3357 "\t" " lwr $t1, 0xC($a1)" "\n"
3358 "\t" " lwl $t2, 0x13($a1)" "\n"
3359 "\t" " lwr $t2, 0x10($a1)" "\n"
3360 "\t" " lwl $t3, 0x17($a1)" "\n"
3361 "\t" " lwr $t3, 0x14($a1)" "\n"
3362 "\t" " lwl $t4, 0x1B($a1)" "\n"
3363 "\t" " lwr $t4, 0x18($a1)" "\n"
3364 "\t" " lwl $t5, 0x1F($a1)" "\n"
3365 "\t" " lwr $t5, 0x1C($a1)" "\n"
3366 "\t" " lwl $t6, 0x23($a1)" "\n"
3367 "\t" " lwr $t6, 0x20($a1)" "\n"
3368 "\t" " lwl $t7, 0x27($a1)" "\n"
3369 "\t" " lwr $t7, 0x24($a1)" "\n"
3370 "\t" " lwl $t8, 0x2B($a1)" "\n"
3371 "\t" " lwr $t8, 0x28($a1)" "\n"
3372 "\t" " lwl $t9, 0x2F($a1)" "\n"
3373 "\t" " lwr $t9, 0x2C($a1)" "\n"
3374 "\t" " addiu $a3, $a3, -0x1" "\n"
3375 "\t" " swl $v0, 0x3($a0)" "\n"
3376 "\t" " swr $v0, 0x0($a0)" "\n"
3377 "\t" " swl $v1, 0x7($a0)" "\n"
3378 "\t" " swr $v1, 0x4($a0)" "\n"
3379 "\t" " swl $t0, 0xB($a0)" "\n"
3380 "\t" " swr $t0, 0x8($a0)" "\n"
3381 "\t" " swl $t1, 0xF($a0)" "\n"
3382 "\t" " swr $t1, 0xC($a0)" "\n"
3383 "\t" " swl $t2, 0x13($a0)" "\n"
3384 "\t" " swr $t2, 0x10($a0)" "\n"
3385 "\t" " swl $t3, 0x17($a0)" "\n"
3386 "\t" " swr $t3, 0x14($a0)" "\n"
3387 "\t" " swl $t4, 0x1B($a0)" "\n"
3388 "\t" " swr $t4, 0x18($a0)" "\n"
3389 "\t" " swl $t5, 0x1F($a0)" "\n"
3390 "\t" " swr $t5, 0x1C($a0)" "\n"
3391 "\t" " swl $t6, 0x23($a0)" "\n"
3392 "\t" " swr $t6, 0x20($a0)" "\n"
3393 "\t" " swl $t7, 0x27($a0)" "\n"
3394 "\t" " swr $t7, 0x24($a0)" "\n"
3395 "\t" " swl $t8, 0x2B($a0)" "\n"
3396 "\t" " swr $t8, 0x28($a0)" "\n"
3397 "\t" " swl $t9, 0x2F($a0)" "\n"
3398 "\t" " swr $t9, 0x2C($a0)" "\n"
3399 "\t" " addiu $a1, $a1, 0x30" "\n"
3400 "\t" " bnez $a3, .Loptimized_memcpy_5" "\n"
3401 "\t" " addiu $a0, $a0, 0x30" "\n"
3402 "\t" " j .Loptimized_memcpy_12" "\n"
3403 "\t" " nop" "\n"
3404 "\t" ".Loptimized_memcpy_6:" "\n"
3405 "\t" " andi $a3, $a0, 0x3" "\n"
3406 "\t" " beqz $a3, .Loptimized_memcpy_9" "\n"
3407 "\t" " nop" "\n"
3408 "\t" " srl $a3, $a2, 2" "\n"
3409 "\t" " addiu $at, $zero, 0xC" "\n"
3410 "\t" " div $zero, $a3, $at" "\n"
3411 "\t" " mflo $a3" "\n"
3412 "\t" " mfhi $v1" "\n"
3413 "\t" " beqz $v1, .Loptimized_memcpy_8" "\n"
3414 "\t" " nop" "\n"
3415 "\t" ".Loptimized_memcpy_7:" "\n"
3416 "\t" " lw $v0, 0x0($a1)" "\n"
3417 "\t" " addiu $v1, $v1, -0x1" "\n"
3418 "\t" " swl $v0, 0x3($a0)" "\n"
3419 "\t" " swr $v0, 0x0($a0)" "\n"
3420 "\t" " addiu $a1, $a1, 0x4" "\n"
3421 "\t" " bnez $v1, .Loptimized_memcpy_7" "\n"
3422 "\t" " addiu $a0, $a0, 0x4" "\n"
3423 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3424 "\t" " nop" "\n"
3425 "\t" ".Loptimized_memcpy_8:" "\n"
3426 "\t" " lw $v0, 0x0($a1)" "\n"
3427 "\t" " lw $v1, 0x4($a1)" "\n"
3428 "\t" " lw $t0, 0x8($a1)" "\n"
3429 "\t" " lw $t1, 0xC($a1)" "\n"
3430 "\t" " lw $t2, 0x10($a1)" "\n"
3431 "\t" " lw $t3, 0x14($a1)" "\n"
3432 "\t" " lw $t4, 0x18($a1)" "\n"
3433 "\t" " lw $t5, 0x1C($a1)" "\n"
3434 "\t" " lw $t6, 0x20($a1)" "\n"
3435 "\t" " lw $t7, 0x24($a1)" "\n"
3436 "\t" " lw $t8, 0x28($a1)" "\n"
3437 "\t" " lw $t9, 0x2C($a1)" "\n"
3438 "\t" " addiu $a3, $a3, -0x1" "\n"
3439 "\t" " swl $v0, 0x3($a0)" "\n"
3440 "\t" " swr $v0, 0x0($a0)" "\n"
3441 "\t" " swl $v1, 0x7($a0)" "\n"
3442 "\t" " swr $v1, 0x4($a0)" "\n"
3443 "\t" " swl $t0, 0xB($a0)" "\n"
3444 "\t" " swr $t0, 0x8($a0)" "\n"
3445 "\t" " swl $t1, 0xF($a0)" "\n"
3446 "\t" " swr $t1, 0xC($a0)" "\n"
3447 "\t" " swl $t2, 0x13($a0)" "\n"
3448 "\t" " swr $t2, 0x10($a0)" "\n"
3449 "\t" " swl $t3, 0x17($a0)" "\n"
3450 "\t" " swr $t3, 0x14($a0)" "\n"
3451 "\t" " swl $t4, 0x1B($a0)" "\n"
3452 "\t" " swr $t4, 0x18($a0)" "\n"
3453 "\t" " swl $t5, 0x1F($a0)" "\n"
3454 "\t" " swr $t5, 0x1C($a0)" "\n"
3455 "\t" " swl $t6, 0x23($a0)" "\n"
3456 "\t" " swr $t6, 0x20($a0)" "\n"
3457 "\t" " swl $t7, 0x27($a0)" "\n"
3458 "\t" " swr $t7, 0x24($a0)" "\n"
3459 "\t" " swl $t8, 0x2B($a0)" "\n"
3460 "\t" " swr $t8, 0x28($a0)" "\n"
3461 "\t" " swl $t9, 0x2F($a0)" "\n"
3462 "\t" " swr $t9, 0x2C($a0)" "\n"
3463 "\t" " addiu $a1, $a1, 0x30" "\n"
3464 "\t" " bnez $a3, .Loptimized_memcpy_8" "\n"
3465 "\t" " addiu $a0, $a0, 0x30" "\n"
3466 "\t" " j .Loptimized_memcpy_12" "\n"
3467 "\t" " nop" "\n"
3468 "\t" ".Loptimized_memcpy_9:" "\n"
3469 "\t" " srl $a3, $a2, 2" "\n"
3470 "\t" " addiu $at, $zero, 0xC" "\n"
3471 "\t" " div $zero, $a3, $at" "\n"
3472 "\t" " mflo $a3" "\n"
3473 "\t" " mfhi $v1" "\n"
3474 "\t" " beqz $v1, .Loptimized_memcpy_11" "\n"
3475 "\t" " nop" "\n"
3476 "\t" ".Loptimized_memcpy_10:" "\n"
3477 "\t" " lwl $v0, 0x3($a1)" "\n"
3478 "\t" " lwr $v0, 0x0($a1)" "\n"
3479 "\t" " addiu $v1, $v1, -0x1" "\n"
3480 "\t" " sw $v0, 0x0($a0)" "\n"
3481 "\t" " addiu $a1, $a1, 0x4" "\n"
3482 "\t" " bnez $v1, .Loptimized_memcpy_10" "\n"
3483 "\t" " addiu $a0, $a0, 0x4" "\n"
3484 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3485 "\t" " nop" "\n"
3486 "\t" ".Loptimized_memcpy_11:" "\n"
3487 "\t" " lwl $v0, 0x3($a1)" "\n"
3488 "\t" " lwr $v0, 0x0($a1)" "\n"
3489 "\t" " lwl $v1, 0x7($a1)" "\n"
3490 "\t" " lwr $v1, 0x4($a1)" "\n"
3491 "\t" " lwl $t0, 0xB($a1)" "\n"
3492 "\t" " lwr $t0, 0x8($a1)" "\n"
3493 "\t" " lwl $t1, 0xF($a1)" "\n"
3494 "\t" " lwr $t1, 0xC($a1)" "\n"
3495 "\t" " lwl $t2, 0x13($a1)" "\n"
3496 "\t" " lwr $t2, 0x10($a1)" "\n"
3497 "\t" " lwl $t3, 0x17($a1)" "\n"
3498 "\t" " lwr $t3, 0x14($a1)" "\n"
3499 "\t" " lwl $t4, 0x1B($a1)" "\n"
3500 "\t" " lwr $t4, 0x18($a1)" "\n"
3501 "\t" " lwl $t5, 0x1F($a1)" "\n"
3502 "\t" " lwr $t5, 0x1C($a1)" "\n"
3503 "\t" " lwl $t6, 0x23($a1)" "\n"
3504 "\t" " lwr $t6, 0x20($a1)" "\n"
3505 "\t" " lwl $t7, 0x27($a1)" "\n"
3506 "\t" " lwr $t7, 0x24($a1)" "\n"
3507 "\t" " lwl $t8, 0x2B($a1)" "\n"
3508 "\t" " lwr $t8, 0x28($a1)" "\n"
3509 "\t" " lwl $t9, 0x2F($a1)" "\n"
3510 "\t" " lwr $t9, 0x2C($a1)" "\n"
3511 "\t" " addiu $a3, $a3, -0x1" "\n"
3512 "\t" " sw $v0, 0x0($a0)" "\n"
3513 "\t" " sw $v1, 0x4($a0)" "\n"
3514 "\t" " sw $t0, 0x8($a0)" "\n"
3515 "\t" " sw $t1, 0xC($a0)" "\n"
3516 "\t" " sw $t2, 0x10($a0)" "\n"
3517 "\t" " sw $t3, 0x14($a0)" "\n"
3518 "\t" " sw $t4, 0x18($a0)" "\n"
3519 "\t" " sw $t5, 0x1C($a0)" "\n"
3520 "\t" " sw $t6, 0x20($a0)" "\n"
3521 "\t" " sw $t7, 0x24($a0)" "\n"
3522 "\t" " sw $t8, 0x28($a0)" "\n"
3523 "\t" " sw $t9, 0x2C($a0)" "\n"
3524 "\t" " addiu $a1, $a1, 0x30" "\n"
3525 "\t" " bnez $a3, .Loptimized_memcpy_11" "\n"
3526 "\t" " addiu $a0, $a0, 0x30" "\n"
3527 "\t" ".Loptimized_memcpy_12:" "\n"
3528 "\t" " andi $v1, $a2, 0x3" "\n"
3529 "\t" " beqz $v1, .Loptimized_memcpy_14" "\n"
3530 "\t" " nop" "\n"
3531 "\t" ".Loptimized_memcpy_13:" "\n"
3532 "\t" " lb $v0, 0x0($a1)" "\n"
3533 "\t" " addiu $v1, $v1, -0x1" "\n"
3534 "\t" " sb $v0, 0x0($a0)" "\n"
3535 "\t" " addiu $a1, $a1, 0x1" "\n"
3536 "\t" " bnez $v1, .Loptimized_memcpy_13" "\n"
3537 "\t" " addiu $a0, $a0, 0x1" "\n"
3538 "\t" ".Loptimized_memcpy_14:" "\n"
3539 "\t" " addu $v0, $a2, $zero" "\n"
3540 "\t" " jr $ra" "\n"
3541 "\t" " nop" "\n"
3542 "\t" ".set pop" "\n"
3543);
3544// clang-format on
3545
3546#ifdef DEAD_CODE
3547void hex_dump(u8 *addr_start, int length)
3548{
3549 int i;
3550
3551 KPRINTF("Hex Dump addr %08x\n", addr_start);
3552 for ( i = 0; i < length; i += 1 )
3553 {
3554 if ( !(i & 0xF) && i )
3555 {
3556 PRINTF("\n");
3557 }
3558 KPRINTF(" %02x", addr_start[i]);
3559 }
3560 KPRINTF("\n");
3561}
3562#endif
3563
3564static int cdvdman_initcfg(void)
3565{
3566 int i;
3567 u8 m_version[5];
3568 u32 eflag;
3569
3570 eflag = 0;
3571 for ( i = 0; i <= 100; i += 1 )
3572 {
3573 unsigned int mvored;
3574
3575#ifdef CDVD_VARIANT_XOSD
3576 if ( !sceCdMV(m_version, &eflag) )
3577#else
3578 if ( !sceCdMV(m_version, &eflag) && (eflag & 0x80) )
3579#endif
3580 {
3581 vDelayThread(2000);
3582 VERBOSE_KPRINTF(1, "_sceCdMV error\n");
3583 }
3584 mvored = m_version[3] | (m_version[2] << 8) | (m_version[1] << 16);
3585 g_cdvdman_emudvd9 = m_version[2] & 1;
3586 VERBOSE_KPRINTF(1, "MV %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3587 g_cdvdman_minver_10700 = mvored >= 0x10700;
3588 g_cdvdman_minver_20200 = mvored >= 0x20200;
3589 g_cdvdman_minver_20400 = mvored >= 0x20400;
3590 g_cdvdman_minver_20800 = mvored >= 0x20800;
3591 g_cdvdman_minver_50000 = mvored >= 0x50000;
3592 g_cdvdman_minver_50200 = mvored >= 0x50200;
3593 g_cdvdman_minver_50400 = mvored >= 0x50400;
3594 g_cdvdman_minver_50600 = mvored >= 0x50600;
3595#ifdef CDVD_VARIANT_XOSD
3596 VERBOSE_KPRINTF(0, "M Version %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3597 if ( cdvdman_get_renewal_date(m_version, &eflag) )
3598 {
3599 VERBOSE_KPRINTF(
3600 0,
3601 "M Renewal Date 20%02x/%02x/%02x %02x:%02x\n",
3602 m_version[0],
3603 m_version[1],
3604 m_version[2],
3605 m_version[3],
3606 m_version[4]);
3607 }
3608 g_cdvdman_vernotxxx1x = 0;
3609 if ( g_cdvdman_minver_50600 )
3610 {
3611 // cdvdman_verxxxx1 = (mvored & 0xF) == 1; // not referenced!
3612 KPRINTF("X_model ");
3613 switch ( mvored & 0xF0 )
3614 {
3615 case 0x00:
3616 KPRINTF("量産 OR 量産試作機\n");
3617 break;
3618 case 0x10:
3619 KPRINTF("原理試作機\n");
3620 g_cdvdman_vernotxxx1x = 1;
3621 break;
3622 case 0x20:
3623 KPRINTF("手作り試作機\n");
3624 break;
3625 case 0x30:
3626 KPRINTF("型物試作機\n");
3627 break;
3628 default:
3629 KPRINTF("Unkown\n");
3630 break;
3631 }
3632 }
3633 else
3634 {
3635 KPRINTF("X_model 旧原理試作機 Ver5.6未満 Found\n");
3636 }
3637#endif
3638 g_cdvdman_minver_x_model_15 = (mvored & 0xF) == 1;
3639 g_cdvdman_minver_60000 = mvored >= 0x60000;
3640 g_cdvdman_minver_60200 = mvored >= 0x60200;
3641#ifdef CDVD_VARIANT_OSD
3642 g_cdvdman_minver_60600 = mvored >= 0x60600;
3643#endif
3644 return 1;
3645 }
3646 return 0;
3647}
3648
3649static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *arg), void *arg)
3650{
3651 return (QueryIntrContext() ? iSetAlarm : SetAlarm)(sys_clock, alarm_cb, arg);
3652}
3653
3654static int vCancelAlarm(unsigned int (*alarm_cb)(void *arg), void *arg)
3655{
3656 return (QueryIntrContext() ? iCancelAlarm : CancelAlarm)(alarm_cb, arg);
3657}
3658
3659#ifdef DEAD_CODE
3660s32 vSignalSema(s32 sema_id)
3661{
3662 return (QueryIntrContext() ? iSignalSema : SignalSema)(sema_id);
3663}
3664#endif
3665
3666static int vSetEventFlag(int ef, u32 bits)
3667{
3668 return (QueryIntrContext() ? iSetEventFlag : SetEventFlag)(ef, bits);
3669}
3670
3671static int vClearEventFlag(int ef, u32 bits)
3672{
3673 return (QueryIntrContext() ? iClearEventFlag : ClearEventFlag)(ef, bits);
3674}
3675
3676static int vReferEventFlagStatus(int ef, iop_event_info_t *info)
3677{
3678 return (QueryIntrContext() ? iReferEventFlagStatus : ReferEventFlagStatus)(ef, info);
3679}
3680
3681static int vPollEventFlag(int ef, u32 bits, int mode, u32 *efbits)
3682{
3683#ifdef CDVD_VARIANT_XOSD
3684 int retres;
3685 iop_event_info_t efinfo;
3686
3687 if ( !QueryIntrContext() )
3688 {
3689 return PollEventFlag(ef, bits, mode, efbits);
3690 }
3691 retres = iReferEventFlagStatus(ef, &efinfo);
3692 if ( retres )
3693 {
3694 return retres;
3695 }
3696 *efbits = efinfo.currBits;
3697 if ( (mode & 1) ? !(efinfo.currBits & bits) : ((efinfo.currBits & bits) != bits) )
3698 {
3699 return KE_EVF_COND;
3700 }
3701 if ( mode & 0x10 )
3702 {
3703 iClearEventFlag(ef, ~bits);
3704 }
3705 return 0;
3706#else
3707 return PollEventFlag(ef, bits, mode, efbits);
3708#endif
3709}
3710
3711static int vDelayThread(int usec)
3712{
3713 int intrval;
3714 int state;
3715
3716 intrval = CpuSuspendIntr(&state);
3717 CpuResumeIntr(state);
3718 return (!QueryIntrContext() && !intrval) ? DelayThread(usec) : 0;
3719}
3720
3721#ifdef CDVD_VARIANT_XOSD
3722static int get_cdvd_register(int regnr)
3723{
3724 int intrres;
3725 int IntrContext;
3726 int regval;
3727 iop_event_info_t efinfo;
3728 int state;
3729 u32 efbits;
3730
3731 intrres = CpuSuspendIntr(&state);
3732 CpuResumeIntr(state);
3733 IntrContext = QueryIntrContext();
3734 if ( !IntrContext && !intrres )
3735 {
3736 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3737 CpuSuspendIntr(&state);
3738 }
3739 else
3740 {
3741 if ( IntrContext )
3742 {
3743 iReferEventFlagStatus(g_cdvdman_csys_evfid, &efinfo);
3744 }
3745 else
3746 {
3747 ReferEventFlagStatus(g_cdvdman_csys_evfid, &efinfo);
3748 }
3749 if ( !(efinfo.currBits & 1) )
3750 {
3751 return -1;
3752 }
3753 }
3754 if ( update_cd_mode_ps2_atapi() != 1 )
3755 {
3756 regval = ((vu8 *)(0xBF402000))[regnr];
3757 }
3758 else
3759 {
3760 if ( !IntrContext && !intrres )
3761 {
3762 CpuResumeIntr(state);
3763 if ( g_cd_atapi_evfid != -1 )
3764 {
3765 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
3766 }
3767 if ( g_adma_evfid != -1 )
3768 {
3769 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3770 }
3771 if ( g_acmd_evfid != -1 )
3772 {
3773 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3774 }
3775 CpuSuspendIntr(&state);
3776 }
3777 else
3778 {
3779 if ( g_cd_atapi_evfid != -1 )
3780 {
3781 if ( IntrContext )
3782 {
3783 iReferEventFlagStatus(g_cd_atapi_evfid, &efinfo);
3784 }
3785 else
3786 {
3787 ReferEventFlagStatus(g_cd_atapi_evfid, &efinfo);
3788 }
3789 if ( !(efinfo.currBits & 3) )
3790 {
3791 return -1;
3792 }
3793 }
3794 if ( g_adma_evfid != -1 )
3795 {
3796 if ( IntrContext )
3797 {
3798 iReferEventFlagStatus(g_adma_evfid, &efinfo);
3799 }
3800 else
3801 {
3802 ReferEventFlagStatus(g_adma_evfid, &efinfo);
3803 }
3804 if ( !(efinfo.currBits & 1) )
3805 {
3806 return -1;
3807 }
3808 }
3809 if ( g_acmd_evfid != -1 )
3810 {
3811 if ( IntrContext )
3812 {
3813 iReferEventFlagStatus(g_acmd_evfid, &efinfo);
3814 }
3815 else
3816 {
3817 ReferEventFlagStatus(g_acmd_evfid, &efinfo);
3818 }
3819 }
3820 if ( !(efinfo.currBits & 1) )
3821 {
3822 return -1;
3823 }
3824 }
3825 set_cdvd_dev5_base_addr_atapi(2);
3826 regval = ((vu8 *)(0xBF402000))[regnr];
3827 set_cdvd_dev5_base_addr_atapi(1);
3828 if ( !IntrContext && !intrres )
3829 {
3830 if ( g_acmd_evfid != -1 )
3831 {
3832 SetEventFlag(g_acmd_evfid, 1);
3833 }
3834 if ( g_adma_evfid != -1 )
3835 {
3836 SetEventFlag(g_adma_evfid, 1);
3837 }
3838 if ( g_cd_atapi_evfid != -1 )
3839 {
3840 SetEventFlag(g_cd_atapi_evfid, 3);
3841 }
3842 }
3843 }
3844 if ( !IntrContext && !intrres )
3845 {
3846 CpuResumeIntr(state);
3847 SetEventFlag(g_cdvdman_csys_evfid, 1);
3848 }
3849 return regval;
3850}
3851#endif
3852
3853// cppcheck-suppress constParameterCallback
3854static unsigned int read_timeout_alarm_cb(void *userdata)
3855{
3856 int read_timeout;
3857 const iop_sys_clock_t *sys_clock;
3858
3859 sys_clock = (const iop_sys_clock_t *)userdata;
3860 read_timeout = sys_clock->lo / 0x9000;
3861 KPRINTF("Read Time Out %d(msec)\n", read_timeout);
3862 sceCdSC(0xFFFFFFEE, &read_timeout);
3863 return !sceCdBreak();
3864}
3865
3867{
3868 sceCdCBFunc rc;
3869 u32 efbits;
3870
3871 if ( sceCdSync(1) || PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
3872 {
3873 return 0;
3874 }
3875 rc = g_cdvdman_user_cb;
3876 g_cdvdman_user_cb = function;
3877 vSetEventFlag(g_ncmd_evfid, 1);
3878 return rc;
3879}
3880
3881// cppcheck-suppress funcArgNamesDifferent
3882void *sceCdPOffCallback(void (*func)(void *userdata), void *userdata)
3883{
3884 void *old_cb;
3885 int state;
3886
3887 CpuSuspendIntr(&state);
3888 old_cb = g_cdvdman_power_off_callback;
3889 g_cdvdman_power_off_callback = func;
3890 g_cdvdman_power_off_callback_userdata = userdata;
3891 CpuResumeIntr(state);
3892 return old_cb;
3893}
3894
3895#ifdef CDVD_VARIANT_XOSD
3896void *sceCdSetAtapiEjectCallback(int (*func)(int reason, void *userdata), void *userdata)
3897{
3898 void *old_cb;
3899 int state;
3900
3901 CpuSuspendIntr(&state);
3902 old_cb = g_cdvdman_atapi_eject_bs_power_callback;
3903 g_cdvdman_atapi_eject_bs_power_callback = func;
3904 g_cdvdman_atapi_eject_bs_power_callback_userdata = userdata;
3905 CpuResumeIntr(state);
3906 return old_cb;
3907}
3908#endif
3909
3910int sceCdstm0Cb(void (*p)(int val))
3911{
3912 g_cdvdman_cdstm0cb = p;
3913 return 0;
3914}
3915
3916int sceCdstm1Cb(void (*p)(int val))
3917{
3918 g_cdvdman_cdstm1cb = p;
3919 return 0;
3920}
3921
3922static int cdvdman_intr_cb(cdvdman_internal_struct_t *s)
3923{
3924 sceCdRMode cdrmode;
3925 int oldstate;
3926 int ext_passthrough;
3927 USE_DEV5_MMIO_HWPORT();
3928
3929 ext_passthrough = 0;
3930 s->m_wait_flag = s->m_waf_set_test;
3931 iSetEventFlag(g_cdvdman_intr_evfid, 0x29);
3932 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
3933 if ( s->m_cdvdman_command == SCECdFuncStandby && s->m_last_error == SCECdErTRMOPN )
3934 {
3935 s->m_last_error = (sceCdStatus() == SCECdErFAIL) ? SCECdErTRMOPN : SCECdErNO;
3936 }
3937 if ( s->m_last_error == SCECdErEOM )
3938 {
3939 s->m_last_error = SCECdErNO;
3940 }
3941 VERBOSE_KPRINTF(
3942 1, "Intr call func_num: %d Err= %02x OnTout= %d\n", g_cdvdman_cmdfunc, (u8)s->m_last_error, s->m_last_read_timeout);
3943 if ( !s->m_scmd_flag )
3944 {
3945 cdvdman_write_scmd(s);
3946 }
3947 if (
3948 (((u8)s->m_last_error == SCECdErREAD && g_cdvdman_cmdfunc == SCECdFuncRead)
3949 || ((u8)s->m_last_error == SCECdErABRT && s->m_last_read_timeout && g_cdvdman_last_cmdfunc == SCECdFuncRead))
3950 && !g_cdvdman_minver_20200 && !s->m_stream_flag && !s->m_dvd_flag && !s->m_recover_status
3951 && s->m_read_mode.trycount != 1 )
3952 {
3953 s->m_sync_error = 0;
3954 s->m_interupt_read_state = 0;
3955 if ( s->m_dec_mode_set )
3956 {
3957 s->m_dec_mode_last_set = 1;
3958 }
3959 else
3960 {
3961 VERBOSE_KPRINTF(1, "dec mode 0x00\n");
3962 s->m_read_chunk_reprocial_32 = 1 + (0x20 / ((!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk));
3963 s->m_dintrlsn = (s->m_read_lsn < 0x61) ? (s->m_read_lsn + s->m_read_sectors + 48) : (s->m_read_lsn - 80);
3964 s->m_read_mode.spindlctrl = 16;
3965 if ( !sceCdRead0_Rty(
3966 s->m_dintrlsn,
3967 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
3968 s->m_read_buf,
3969 &s->m_read_mode,
3970 (u8)s->m_cdvdman_command,
3971 0,
3972 0) )
3973 {
3974 s->m_last_error = SCECdErREAD;
3975 s->m_recover_status = 0;
3976 }
3977 else
3978 {
3979 ext_passthrough = 1;
3980 }
3981 }
3982 }
3983 if ( !ext_passthrough )
3984 {
3985 char dev5_reg_013_masked;
3986
3987 VERBOSE_KPRINTF(1, "Recover_Stat:%d\n", s->m_recover_status);
3988 dev5_reg_013_masked = dev5_mmio_hwport->m_dev5_reg_013 & 0xF;
3989 if ( dev5_reg_013_masked )
3990 {
3991 if (
3992 ((u8)s->m_last_error == SCECdErREAD || ((u8)s->m_last_error == SCECdErABRT && s->m_last_read_timeout))
3993 && !s->m_recover_status && !s->m_stream_flag && g_cdvdman_cmdfunc != 9 && g_cdvdman_cmdfunc != SCECdFuncReadCDDA
3994 && (unsigned int)s->m_read_mode.trycount - 1 >= 4 )
3995 {
3996 s->m_sync_error = 0;
3997 s->m_interupt_read_state = 0;
3998 if ( s->m_dec_mode_set )
3999 {
4000 s->m_dec_mode_last_set = 2;
4001 }
4002 else
4003 {
4004 VERBOSE_KPRINTF(1, "dec mode 0x01\n");
4005 cdrmode.trycount = s->m_read_mode.trycount;
4006 cdrmode.spindlctrl = dev5_reg_013_masked + 13;
4007 cdrmode.datapattern = s->m_read_mode.datapattern;
4008 if ( sceCdRead0_Rty(
4009 s->m_read_lsn,
4010 s->m_read_sectors,
4011 s->m_read_buf,
4012 &cdrmode,
4013 (u8)s->m_cdvdman_command,
4014 s->m_read_chunk,
4015 s->m_read_callback) )
4016 {
4017 s->m_last_error = SCECdErNO;
4018 return 1;
4019 }
4020 s->m_last_error = SCECdErREAD;
4021 }
4022 }
4023 }
4024 s->m_last_read_timeout = 0;
4025 switch ( s->m_recover_status )
4026 {
4027 case 1:
4028 s->m_sync_error = 0;
4029 s->m_interupt_read_state = 0;
4030 if (
4031 s->m_last_error != SCECdErNO
4032 || !sceCdRead0_Rty(
4033 s->m_dintrlsn,
4034 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
4035 s->m_read_buf,
4036 &s->m_read_mode,
4037 (u8)s->m_cdvdman_command,
4038 0,
4039 0) )
4040 {
4041 s->m_last_error = SCECdErREAD;
4042 s->m_recover_status = 0;
4043 }
4044 else
4045 {
4046 ext_passthrough = 1;
4047 }
4048 break;
4049 case 2:
4050 s->m_sync_error = 0;
4051 s->m_interupt_read_state = 0;
4052 if ( sceCdRead0(
4053 s->m_read_lsn, s->m_read_sectors, s->m_read_buf, &s->m_read_mode, s->m_read_chunk, s->m_read_callback) )
4054 {
4055 s->m_last_error = SCECdErNO;
4056 s->m_recover_status = 3;
4057 return 1;
4058 }
4059 s->m_last_error = SCECdErREAD;
4060 s->m_recover_status = 0;
4061 break;
4062 case 3:
4063 s->m_recover_status = 0;
4064 break;
4065 default:
4066 break;
4067 }
4068 }
4069 if ( ext_passthrough )
4070 {
4071 s->m_last_error = SCECdErNO;
4072 s->m_dintrlsn += s->m_read_sectors;
4073 s->m_read_chunk_reprocial_32 -= 1;
4074 s->m_recover_status = (!s->m_read_chunk_reprocial_32) ? 2 : 1;
4075 return 1;
4076 }
4077 if ( s->m_dec_state )
4078 {
4079 sceCdDecSet(0, 0, 0);
4080 }
4081 if ( (s->m_read2_flag == 1 || s->m_read2_flag == 3) && !s->m_use_toc )
4082 {
4083 VERBOSE_KPRINTF(1, "call Read2intrCDVD()\n");
4084 Read2intrCDVD(s->m_read2_flag);
4085 }
4086 s->m_sync_error = 0;
4087 s->m_interupt_read_state = 0;
4088 if ( s->m_dec_state == 2 )
4089 {
4090 s->m_dec_state = 0;
4091 }
4092 if ( s->m_stream_flag == 1 && !s->m_use_toc && !s->m_read2_flag )
4093 {
4094 if ( g_cdvdman_cdstm0cb )
4095 {
4096 g_cdvdman_cdstm0cb(1);
4097 }
4098 else
4099 {
4100 VERBOSE_KPRINTF(1, "Intr func0 no seting");
4101 }
4102 }
4103 if ( !s->m_read2_flag )
4104 {
4105 if ( s->m_stream_flag == 2 && !s->m_use_toc )
4106 {
4107 if ( g_cdvdman_cdstm1cb )
4108 {
4109 g_cdvdman_cdstm1cb(1);
4110 }
4111 else
4112 {
4113 VERBOSE_KPRINTF(1, "Intr func1 no seting");
4114 }
4115 }
4116 else
4117 {
4118 g_cdvdman_readptr = 0;
4119 }
4120 }
4121
4122 VERBOSE_KPRINTF(
4123 1, "Intr call user callback func_addr %08x num %d flg %d\n", g_cdvdman_user_cb, g_cdvdman_cmdfunc, s->m_read2_flag);
4124 if ( g_cdvdman_user_cb && g_cdvdman_cmdfunc && !s->m_read2_flag && !s->m_use_toc )
4125 {
4126 int cmdfunc_tmp;
4127
4128 cmdfunc_tmp = g_cdvdman_cmdfunc;
4129 g_cdvdman_cmdfunc = 0;
4130 if ( cmdfunc_tmp == 14 || cmdfunc_tmp == 9 )
4131 {
4132 cmdfunc_tmp = SCECdFuncRead;
4133 }
4134 g_cdvdman_user_cb(cmdfunc_tmp);
4135 }
4136 if ( !g_cdvdman_user_cb )
4137 {
4138 g_cdvdman_cmdfunc = 0;
4139 }
4140 return 1;
4141}
4142
4143static int intrh_cdrom(void *userdata)
4144{
4145 int conds1;
4146 iop_event_info_t efinfo;
4147#ifdef CDVD_VARIANT_XOSD
4148 int condaddr5;
4149#endif
4150 int intr_cb_res;
4152 USE_DEV5_MMIO_HWPORT();
4153
4154 s = (cdvdman_internal_struct_t *)userdata;
4155 conds1 = 0;
4156#ifdef CDVD_VARIANT_XOSD
4157 if ( s->m_cd_mode_ps2_atapi == 1 )
4158 {
4159 int spd_intr_stat_cur;
4160 int atapi_intr_reason;
4161
4162 VERBOSE_KPRINTF(1, "Atapi Intr Called %d\n", g_cdvdman_debug_atapi_intr++);
4163 condaddr5 = (unsigned int)GetBaseAddress(5) == 0x1F402000;
4164 set_cdvd_dev5_base_addr_atapi(1);
4165 (void)*(vu16 *)0xBF410028; // r_spd_intr_stat
4166 set_cdvd_dev5_base_addr_atapi(2);
4167 atapi_intr_reason = dev5_mmio_hwport->m_dev5_reg_008;
4168 if ( (atapi_intr_reason & 1) )
4169 {
4170 conds1 = 1;
4171 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4172 VERBOSE_KPRINTF(1, "ATAPI DRAGON CMDCMPL Interrupt\n");
4173 }
4174 if ( atapi_intr_reason & 4 )
4175 {
4176 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4177 conds1 = 1;
4178 iSetEventFlag(g_cdvdman_intr_evfid, 4);
4179 iSetEventFlag(g_cdvdman_intr_evfid, 0x10);
4180 set_cdvd_dev5_base_addr_atapi(1);
4181 VERBOSE_KPRINTF(1, "ATAPI POFFRDY Interrupt\n");
4182 if ( g_cdvdman_power_off_callback )
4183 {
4184 g_cdvdman_power_off_callback(g_cdvdman_power_off_callback_userdata);
4185 }
4186 set_cdvd_dev5_base_addr_atapi(2);
4187 }
4188 if ( (atapi_intr_reason & 8) )
4189 {
4190 conds1 = 1;
4191 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4192 if ( !s->m_medium_removal_state )
4193 {
4194 s->m_atapi_disk_ejected = 0;
4195 }
4196 set_cdvd_dev5_base_addr_atapi(1);
4197 VERBOSE_KPRINTF(1, "ATAPI EJECT Interrupt\n");
4198 if ( s->m_cd_atapi_intr_callback && !s->m_medium_removal_state )
4199 {
4200 VERBOSE_KPRINTF(1, "EJECT Stop Call\n");
4201 s->m_cd_atapi_intr_callback(1);
4202 }
4203 iSetEventFlag(g_cdvdman_intr_evfid, 0x40);
4204 if ( g_cdvdman_atapi_eject_bs_power_callback )
4205 {
4206 VERBOSE_KPRINTF(1, "ATAPI EJECT Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4207 g_cdvdman_atapi_eject_bs_power_callback(1, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4208 }
4209 set_cdvd_dev5_base_addr_atapi(2);
4210 }
4211 if ( (atapi_intr_reason & 0x10) )
4212 {
4213 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4214 conds1 = 1;
4215 set_cdvd_dev5_base_addr_atapi(1);
4216 VERBOSE_KPRINTF(1, "ATAPI BS_Power DET Interrupt\n");
4217 iSetEventFlag(g_cdvdman_intr_evfid, 0x80);
4218 if ( g_cdvdman_atapi_eject_bs_power_callback )
4219 {
4220 VERBOSE_KPRINTF(1, "ATAPI BS_Power Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4221 g_cdvdman_atapi_eject_bs_power_callback(2, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4222 }
4223 }
4224 set_cdvd_dev5_base_addr_atapi(1);
4225 if ( g_cdvdman_vernotxxx1x && conds1 )
4226 {
4227 *(vu16 *)0xBF41002A &= ~0x100; // r_spd_intr_mask
4228 *(vu16 *)0xBF41002A |= 0x100; // r_spd_intr_mask
4229 (void)*(vu16 *)0xBF41002A; // r_spd_intr_mask
4230 }
4231 spd_intr_stat_cur = *(vu16 *)0xBF410028; // r_spd_intr_stat
4232 VERBOSE_KPRINTF(
4233 1,
4234 "Atapi Intr Mode:%d addr:%08x Reason:%02x SPD_INTR_STAT %x\n",
4235 s->m_cd_mode_ps2_atapi,
4236 s->m_cd_atapi_intr_callback,
4237 atapi_intr_reason,
4238 spd_intr_stat_cur);
4239 if ( (spd_intr_stat_cur & 3) && (*g_cdvdreg_bf80146c & 4) )
4240 {
4241 if ( s->m_cd_atapi_intr_callback )
4242 {
4243 s->m_cd_atapi_intr_callback(0);
4244 VERBOSE_KPRINTF(1, "Atapi Intr called\n");
4245 }
4246 if ( !s->m_scmd_flag )
4247 {
4248 VERBOSE_KPRINTF(1, "Intr call set_prev_command.\n");
4249 set_cdvd_dev5_base_addr_atapi(2);
4250 cdvdman_write_scmd(s);
4251 set_cdvd_dev5_base_addr_atapi(1);
4252 }
4253 }
4254 else if ( !conds1 )
4255 {
4256 if ( (*g_cdvdreg_bf80146c & 4) )
4257 {
4258 VERBOSE_KPRINTF(1, "No_Reason Intr\n");
4259 }
4260 else
4261 {
4262 VERBOSE_KPRINTF(1, "already 9611 Power Off Intr\n");
4263 }
4264 }
4265 if ( condaddr5 )
4266 {
4267 set_cdvd_dev5_base_addr_atapi(2);
4268 VERBOSE_KPRINTF(1, "Cur PS2 IO Intr Called\n");
4269 }
4270 return 1;
4271 }
4272 VERBOSE_KPRINTF(1, "Dragon Intr Called\n");
4273 condaddr5 = (unsigned int)GetBaseAddress(5) == 0xBF410000;
4274 if ( condaddr5 )
4275 {
4276 set_cdvd_dev5_base_addr_atapi(2);
4277 }
4278#endif
4279 s->m_waf_set_test = s->m_wait_flag;
4280 if ( (u8)s->m_last_error != SCECdErABRT )
4281 {
4282 s->m_last_error = dev5_mmio_hwport->m_dev5_reg_006;
4283 }
4284 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4285 {
4286 s->m_waf_set_test = (!(dev5_mmio_hwport->m_dev5_reg_005 & 1)) ? 1 : -1;
4287 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4288 conds1 = 1;
4289 }
4290 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4291 {
4292 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4293 iSetEventFlag(g_cdvdman_intr_evfid, 4);
4294 iSetEventFlag(g_cdvdman_intr_evfid, 0x10);
4295 // The following Kprintf was added for ioprp300x
4296 VERBOSE_KPRINTF(1, "PS2 POWER OFF Interrupt\n");
4297 if ( g_cdvdman_power_off_callback )
4298 {
4299 g_cdvdman_power_off_callback(g_cdvdman_power_off_callback_userdata);
4300 }
4301 if ( !conds1 )
4302 {
4303 return 1;
4304 }
4305 }
4306 else
4307 {
4308 s->m_waf_set_test = 1;
4309 s->m_ncmd_intr_count += 1;
4310 dev5_mmio_hwport->m_dev5_reg_008 = 2;
4311 }
4312#ifdef CDVD_VARIANT_XOSD
4313 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 8) )
4314 {
4315 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4316 VERBOSE_KPRINTF(1, "PS2 EJECT Interrupt\n");
4317 iSetEventFlag(g_cdvdman_intr_evfid, 0x40);
4318 if ( !s->m_medium_removal_state )
4319 {
4320 s->m_atapi_disk_ejected = 0;
4321 }
4322 if ( g_cdvdman_atapi_eject_bs_power_callback )
4323 {
4324 VERBOSE_KPRINTF(1, "PS2 EJECT Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4325 g_cdvdman_atapi_eject_bs_power_callback(1, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4326 }
4327 }
4328 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 0x10) )
4329 {
4330 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4331 VERBOSE_KPRINTF(1, "PS2 BS_Power DET Interrupt\n");
4332 iSetEventFlag(g_cdvdman_intr_evfid, 0x80);
4333 if ( g_cdvdman_atapi_eject_bs_power_callback )
4334 {
4335 VERBOSE_KPRINTF(1, "PS2 BS_Power Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4336 g_cdvdman_atapi_eject_bs_power_callback(2, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4337 }
4338 }
4339#endif
4340 iReferEventFlagStatus(g_cdvdman_intr_evfid, &efinfo);
4341 if ( !(efinfo.currBits & 0x20) )
4342 {
4343 // The following Kprintf was added for ioprp300x
4344 VERBOSE_KPRINTF(1, "Now DMA Working evfid:%08x\n", efinfo.currBits);
4345 if ( s->m_last_error == SCECdErNO )
4346 {
4347 s->m_drive_interupt_request = 1;
4348#ifdef CDVD_VARIANT_XOSD
4349 if ( condaddr5 )
4350 {
4351 set_cdvd_dev5_base_addr_atapi(1);
4352 }
4353#endif
4354 return 1;
4355 }
4356 if ( s->m_last_error == SCECdErEOM )
4357 {
4358 intrh_dma_3(s);
4359 }
4360 }
4361 intr_cb_res = cdvdman_intr_cb(s);
4362#ifdef CDVD_VARIANT_XOSD
4363 if ( condaddr5 )
4364 {
4365 set_cdvd_dev5_base_addr_atapi(1);
4366 }
4367#endif
4368 return intr_cb_res;
4369}
4370
4371static u32 cdvdman_l1start(const u8 *toc)
4372{
4373 return toc[23] + (toc[22] << 8) + (toc[21] << 16) - 0x30000 + 1;
4374}
4375
4376static int DvdDual_infochk(void)
4377{
4378#ifdef CDVD_VARIANT_OSD
4379 // From DVD Player 3.11
4380 if ( QueryIntrContext() || !(cdvdman_mediactl(3) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
4381#else
4382 if ( QueryIntrContext() || !(cdvdman_mediactl(4) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
4383#endif
4384 {
4385 return 1;
4386 }
4387 g_cdvdman_istruct.m_use_toc = 1;
4388 if ( !cdvdman_gettoc(g_cdvdman_ptoc) )
4389 {
4390 g_cdvdman_istruct.m_use_toc = 0;
4391 g_cdvdman_istruct.m_opo_or_para = -1;
4392 return 0;
4393 }
4394 g_cdvdman_istruct.m_use_toc = 0;
4395 g_cdvdman_istruct.m_layer_1_lsn = cdvdman_l1start(g_cdvdman_ptoc);
4396 g_cdvdman_istruct.m_opo_or_para = ((g_cdvdman_ptoc[14] & 0x60)) ? (((g_cdvdman_ptoc[14] & 0x10)) ? 2 : 1) : 0;
4397 if ( g_cdvdman_istruct.m_dual_layer_emulation )
4398 {
4399 VERBOSE_KPRINTF(1, "CDVD:DualEmuON\n");
4400 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
4401 g_cdvdman_istruct.m_opo_or_para = 0;
4402 }
4403 VERBOSE_KPRINTF(
4404 1,
4405 "DvdDual_info: %02x\tLayer1_LSN:%d opo_or_para %d\n",
4406 g_cdvdman_ptoc[14],
4407 g_cdvdman_istruct.m_layer_1_lsn,
4408 (u8)g_cdvdman_istruct.m_opo_or_para);
4409 return 1;
4410}
4411
4412static u32 sceCdLsnDualChg(u32 lsn)
4413{
4414 int layer_disk_needed;
4415 u32 change_lsn;
4416 sceCdRMode cdrmode;
4417 int has_change_lsn;
4418
4419 layer_disk_needed = 2;
4420 has_change_lsn = 0;
4421 if ( cdvdman_isdvd() && DvdDual_infochk() )
4422 {
4423 if ( g_cdvdman_istruct.m_dual_layer_emulation )
4424 {
4425 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
4426 {
4427 layer_disk_needed = 1;
4428 }
4429 if ( g_cdvdman_istruct.m_current_dvd && lsn < g_cdvdman_istruct.m_current_dvd_lsn )
4430 {
4431 layer_disk_needed = 0;
4432 }
4433 if ( layer_disk_needed == 2 )
4434 {
4435 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
4436 has_change_lsn = 1;
4437 }
4438 else if ( !QueryIntrContext() )
4439 {
4440 u32 traychk;
4441
4442 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
4443 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4444 {
4445 ;
4446 }
4447 cdrmode.trycount = 0;
4448 cdrmode.spindlctrl = SCECdSpinStm;
4449 cdrmode.datapattern = SCECdSecS2048;
4450 g_cdvdman_istruct.m_use_toc = 1;
4451 while ( layer_disk_needed != 2 )
4452 {
4453 if ( cdvdman_isdvd() )
4454 {
4455 int read0_result;
4456
4457 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
4458 sceCdSync(3);
4459 if ( g_cdvdman_istruct.m_last_error == SCECdErNO || read0_result )
4460 {
4461 int i;
4462
4463 for ( i = 0; i < 20; i += 1 )
4464 {
4465 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
4466 {
4467 break;
4468 }
4469 }
4470 if ( i == 20 && g_cdvdman_ptoc[131] == 2 && (g_cdvdman_ptoc[132] & 2) )
4471 {
4472 if ( layer_disk_needed == g_cdvdman_ptoc[133] )
4473 {
4474 g_cdvdman_istruct.m_current_dvd = layer_disk_needed;
4475 layer_disk_needed = 2;
4476 }
4477 else
4478 {
4479 VERBOSE_KPRINTF(0, "CDVD: Layer_%d Disk not Found\n", layer_disk_needed);
4480 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
4481 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
4482 {
4483 layer_disk_needed = 1;
4484 }
4485 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4486 {
4487 ;
4488 }
4489 }
4490 }
4491 else
4492 {
4493 VERBOSE_KPRINTF(0, "CDVD: Not Master Disk %s\n", (const char *)&g_cdvdman_ptoc[i + 104]);
4494 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4495 {
4496 ;
4497 }
4498 }
4499 }
4500 else
4501 {
4502 VERBOSE_KPRINTF(1, "CDVD: LsnDualChg Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
4503 }
4504 }
4505 else
4506 {
4507 vDelayThread(16000);
4508 }
4509 }
4510 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
4511 g_cdvdman_istruct.m_use_toc = 0;
4512 has_change_lsn = 1;
4513 }
4514 }
4515 else
4516 {
4517 change_lsn =
4518 lsn - ((g_cdvdman_istruct.m_opo_or_para && (lsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn)) ? 0x10 : 0);
4519 has_change_lsn = 1;
4520 }
4521 }
4522 if ( has_change_lsn )
4523 {
4524 VERBOSE_KPRINTF(1, "CDVD: sceCdLsnDualChg lsn %d: change lsn %d\n", lsn, change_lsn);
4525 }
4526 return has_change_lsn ? change_lsn : lsn;
4527}
4528
4529int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
4530{
4531 int read0_result;
4532 int i;
4533 sceCdRMode cdrmode;
4534
4535 *on_dual = 0;
4536 *layer1_start = 0;
4537 g_cdvdman_istruct.m_dual_layer_emulation = 0;
4538#ifndef CDVD_VARIANT_XOSD
4539 if ( !cdvdman_isdvd() )
4540 {
4541 return 1;
4542 }
4543#endif
4544 if ( !g_cdvdman_emudvd9 )
4545 {
4546 if ( !DvdDual_infochk() )
4547 {
4548 return 0;
4549 }
4550 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
4551 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4552 return 1;
4553 }
4554#ifdef CDVD_VARIANT_OSD
4555 if ( !cdvdman_isdvd() )
4556 {
4557 return 1;
4558 }
4559#endif
4560#ifndef CDVD_VARIANT_XOSD
4561 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
4562 {
4563 return 0;
4564 }
4565#endif
4566 cdrmode.trycount = 0;
4567 cdrmode.spindlctrl = SCECdSpinStm;
4568 cdrmode.datapattern = SCECdSecS2048;
4569 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
4570 sceCdSync(3);
4571 if ( g_cdvdman_istruct.m_last_error != SCECdErNO && !read0_result )
4572 {
4573 VERBOSE_KPRINTF(1, "CDVD: ReadDvdDualInfo Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
4574 return 0;
4575 }
4576 for ( i = 0; i < 20; i += 1 )
4577 {
4578 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
4579 {
4580 break;
4581 }
4582 }
4583 if ( i != 20 )
4584 {
4585 if ( !DvdDual_infochk() )
4586 {
4587 return 0;
4588 }
4589 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
4590 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4591 return 1;
4592 }
4593 if ( g_cdvdman_ptoc[131] != 2 || !(g_cdvdman_ptoc[132] & 2) )
4594 {
4595 return 1;
4596 }
4597 g_cdvdman_istruct.m_current_dvd = g_cdvdman_ptoc[133];
4598 g_cdvdman_istruct.m_current_dvd_lsn =
4599 g_cdvdman_ptoc[134] + (g_cdvdman_ptoc[135] << 8) + (g_cdvdman_ptoc[136] << 16) + (g_cdvdman_ptoc[137] << 24) + 1;
4600 g_cdvdman_istruct.m_opo_or_para = 0;
4601 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
4602 g_cdvdman_istruct.m_dual_layer_emulation = 1;
4603 *on_dual = 1;
4604 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4605 VERBOSE_KPRINTF(
4606 1,
4607 "sceCdReadDvdDualInfo():Cur_Disk %d layer1_start %d\n",
4608 (u8)g_cdvdman_istruct.m_current_dvd,
4609 g_cdvdman_istruct.m_current_dvd_lsn);
4610 return 1;
4611}
4612
4613int sceCdSC(int code, int *param)
4614{
4615 void *poffarg_tmp;
4616 int *BootMode;
4617 int state;
4618 u32 efbits;
4619#ifdef CDVD_VARIANT_XOSD
4620 u8 regval;
4621#endif
4622
4623 switch ( code )
4624 {
4625#ifdef CDVD_VARIANT_XOSD
4626 case 0xFFFFFFD6:
4627 CpuSuspendIntr(&state);
4628 set_cdvd_dev5_base_addr_atapi(2);
4629 regval = ((vu8 *)(0xBF402000))[*param];
4630 set_cdvd_dev5_base_addr_atapi(1);
4631 CpuResumeIntr(state);
4632 return regval;
4633 case 0xFFFFFFD7:
4634 CpuSuspendIntr(&state);
4635 *param = (int)&g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open;
4636 CpuResumeIntr(state);
4637 return 1;
4638 case 0xFFFFFFD8:
4639 return sc_ffffffd8((u32 *)param);
4640 case 0xFFFFFFD9:
4641 CpuSuspendIntr(&state);
4642 *param = (int)&g_cdvdman_istruct.m_atapi_disk_ejected;
4643 CpuResumeIntr(state);
4644 return 1;
4645 case 0xFFFFFFDA:
4646 return get_disk_type_ex();
4647 case 0xFFFFFFDB:
4648 CpuSuspendIntr(&state);
4649 *(&g_cdvdman_istruct.m_var_sc_ffffffdb) = (int)param;
4650 CpuResumeIntr(state);
4651 return 1;
4652 case 0xFFFFFFDC:
4653 return g_cdvdman_vernotxxx1x;
4654 case 0xFFFFFFDD:
4655 return get_cdvd_register(*param);
4656 case 0xFFFFFFDF:
4657 g_adma_evfid = *param;
4658 return 1;
4659 case 0xFFFFFFE0:
4660 g_acmd_evfid = *param;
4661 return 1;
4662 case 0xFFFFFFE1:
4663 CpuSuspendIntr(&state);
4664 g_cdvdman_istruct.m_chgsys_callback = (void *)(int)param;
4665 CpuResumeIntr(state);
4666 return 1;
4667 case 0xFFFFFFE4:
4668 g_cd_atapi_evfid = *param;
4669 return 1;
4670 case 0xFFFFFFE5:
4671 CpuSuspendIntr(&state);
4672 g_cdvdman_istruct.m_cd_atapi_intr_callback = (void *)(int)param;
4673 CpuResumeIntr(state);
4674 return 1;
4675#endif
4676 case 0xFFFFFFE6:
4677 CpuSuspendIntr(&state);
4678 *param = (int)g_cdvdman_power_off_callback;
4679 poffarg_tmp = g_cdvdman_power_off_callback_userdata;
4680 CpuResumeIntr(state);
4681 return (int)poffarg_tmp;
4682 case 0xFFFFFFE7:
4683 return g_scmd_evfid;
4684 case 0xFFFFFFE9:
4685 return sceCdLsnDualChg(*param);
4686 case 0xFFFFFFEA:
4687 return DvdDual_infochk();
4688 case 0xFFFFFFEE:
4689 g_cdvdman_istruct.m_last_read_timeout = *param;
4690 return 0;
4691 case 0xFFFFFFEF:
4692 return g_cdvdman_stream_timeout;
4693 case 0xFFFFFFF0:
4694 *param = (int)&g_verbose_level;
4695 return 0xFF;
4696 case 0xFFFFFFF1:
4697 return g_cdvdman_sync_timeout;
4698 case 0xFFFFFFF2:
4699 *param = (int)&g_cdvdman_istruct;
4700 return 0xFF;
4701 case 0xFFFFFFF3:
4702 BootMode = QueryBootMode(4);
4703 switch ( BootMode ? *(u8 *)BootMode : 0xFF )
4704 {
4705 case 0:
4706 case 1:
4707 case 2:
4708 g_cdvdman_mmode = 0xFF;
4709 break;
4710 case 3:
4711 g_cdvdman_mmode = SCECdMmodeCd;
4712 break;
4713 default:
4714 break;
4715 }
4716 return 1;
4717 case 0xFFFFFFF4:
4718#ifdef CDVD_VARIANT_OSD
4719 return 1;
4720#else
4721 // The following call to sceCdGetDiskType was inlined
4722 switch ( sceCdGetDiskType() )
4723 {
4724 case SCECdPSCD:
4725 case SCECdPSCDDA:
4726 case SCECdPS2CD:
4727 case SCECdPS2CDDA:
4728 return g_cdvdman_mmode == SCECdMmodeCd || g_cdvdman_mmode == 0xFF;
4729 case SCECdPS2DVD:
4730 return g_cdvdman_mmode == SCECdMmodeDvd || g_cdvdman_mmode == 0xFF;
4731 case SCECdCDDA:
4732 return g_cdvdman_mmode == 0xFF;
4733 default:
4734 return 0;
4735 }
4736#endif
4737 case 0xFFFFFFF5:
4738 return g_cdvdman_intr_evfid;
4739 case 0xFFFFFFF6:
4740 if ( *param )
4741 {
4742 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
4743 }
4744 else
4745 {
4746 SetEventFlag(g_fio_fsv_evfid, 1);
4747 }
4748 g_cdvdman_ee_rpc_fno = *param;
4749 VERBOSE_KPRINTF(1, "EE_ncmd_working code= %d\n", *param);
4750 return g_cdvdman_ee_rpc_fno;
4751 case 0xFFFFFFF7:
4752 return (u16)_irx_id.v;
4753 case 0xFFFFFFF8:
4754 g_cdvdman_spinctl = *param;
4755 return 1;
4756 case 0xFFFFFFFC:
4757 return g_cdvdman_cd36key;
4758 case 0xFFFFFFFD:
4759 return g_cdvdman_istruct.m_read2_flag;
4760 case 0xFFFFFFFE:
4761 g_cdvdman_istruct.m_last_error = *(u8 *)param;
4762 return (u8)g_cdvdman_istruct.m_last_error;
4763 case 0xFFFFFFFF:
4764 case 0:
4765 case 1:
4766 case 2:
4767 *param = (u8)g_cdvdman_istruct.m_last_error;
4768 if ( code != -1 )
4769 {
4770 g_cdvdman_istruct.m_stream_flag = code;
4771 }
4772 return g_cdvdman_istruct.m_stream_flag;
4773 default:
4774 VERBOSE_KPRINTF(1, "sceCdSC func_num Not found %d\n", code);
4775 return 0;
4776 }
4777}
4778
4779static void cdvdman_init(void)
4780{
4781 int *BootMode;
4782 unsigned int i;
4783 int scres_unused;
4784 u32 argres;
4785#ifdef CDVD_VARIANT_XOSD
4786 int chgsys_tmp;
4787#endif
4788 USE_DEV5_MMIO_HWPORT();
4789
4790#ifdef CDVD_VARIANT_XOSD
4791 {
4792 int state;
4793 CpuSuspendIntr(&state);
4794 g_cdvdman_istruct.m_cd_mode_ps2_atapi = 2;
4795 cdvdman_change_drive(2);
4796 CpuResumeIntr(state);
4797 }
4798#endif
4799 g_cdvdman_user_cb = 0;
4800 g_cdvdman_power_off_callback = 0;
4801 g_cdvdman_cmdfunc = 0;
4802 g_cdvdman_istruct.m_drive_interupt_request = 0;
4803 RegisterIntrHandler(IOP_IRQ_CDVD, 1, intrh_cdrom, &g_cdvdman_istruct);
4804 RegisterIntrHandler(IOP_IRQ_DMA_CDVD, 1, intrh_dma_3, &g_cdvdman_istruct);
4805 EnableIntr(IOP_IRQ_CDVD);
4806 sceCdSC(0xFFFFFFF3, &scres_unused);
4807 dmac_set_dpcr(dmac_get_dpcr() | 0x8000);
4808 dmac_ch_set_chcr(3, 0);
4809#ifdef CDVD_VARIANT_XOSD
4810 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 0x10) )
4811 {
4812 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4813 }
4814 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 8) )
4815 {
4816 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4817 }
4818#endif
4819 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4820 {
4821 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4822 }
4823 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4824 {
4825 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4826 }
4827#ifndef CDVD_VARIANT_XOSD
4828 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4829#endif
4830 g_cdvdman_istruct.m_tray_is_open = !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen);
4831#ifdef CDVD_VARIANT_XOSD
4832 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4833#endif
4834 cdvdman_initcfg();
4835 BootMode = QueryBootMode(6);
4836 g_cdvdman_istruct.m_no_dec_flag = BootMode ? ((*(u16 *)BootMode & 0xFFFC) == 0x60) : 0;
4837 for ( i = 0; i <= 60 && (!sceCdCancelPOffRdy(&argres) || argres); i += 1 )
4838 {
4839 DelayThread(16000);
4840 }
4841#ifdef CDVD_VARIANT_XOSD
4842 {
4843 u32 medium_res;
4844 int MediumRemoval;
4845
4846 for ( i = 0; i <= 60 && (!sceCdSetMediumRemoval(0, &argres) || argres); i += 1 )
4847 {
4848 DelayThread(16000);
4849 }
4850 for ( i = 0; i <= 60 && (!(MediumRemoval = sceCdGetMediumRemoval(&medium_res, &argres)) || argres); i += 1 )
4851 {
4852 DelayThread(16000);
4853 }
4854 g_cdvdman_istruct.m_medium_removal_state = (MediumRemoval && !argres) ? medium_res : 0;
4855 {
4856 int state;
4857
4858 CpuSuspendIntr(&state);
4859 chgsys_tmp = (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen);
4860 g_cdvdman_istruct.m_cd_mode_ps2_atapi =
4861 (chgsys_tmp || (!(dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && dev5_mmio_hwport->m_dev5_reg_00F != 6)) ? 2 : 1;
4862 cdvdman_change_drive(g_cdvdman_istruct.m_cd_mode_ps2_atapi);
4863 CpuResumeIntr(state);
4864 }
4865 if ( chgsys_tmp )
4866 {
4867 sceCdChgSys(1);
4868 }
4869 }
4870#endif
4871}
4872
4873int sceCdInit(int mode)
4874{
4875 VERBOSE_PRINTF(1, "sceCdInit called mode= %d\n", mode);
4876 if ( mode == SCECdEXIT )
4877 {
4878 int oldstate;
4879
4880 g_cdvdman_istruct.m_cd_inited = 0;
4881#ifndef CDVD_VARIANT_XOSD
4882 sceCdBreak();
4883 sceCdSync(3);
4884 cdvdman_ncmd_sender_06();
4885#endif
4886 sceCdSync(0);
4887 VERBOSE_PRINTF(1, "Cdvdman Exit\n");
4888 DisableIntr(IOP_IRQ_CDVD, &oldstate);
4889 ReleaseIntrHandler(IOP_IRQ_CDVD);
4890 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
4891 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
4892 }
4893 else
4894 {
4895 VERBOSE_PRINTF(1, "Cdvdman Init\n");
4896 g_cdvdman_istruct.m_read2_flag = 0;
4897 g_cdvdman_istruct.m_dec_shift = 0;
4898 g_cdvdman_istruct.m_check_version = 0;
4899 g_cdvdman_istruct.m_dec_state = 0;
4900#ifdef CDVD_VARIANT_XOSD
4901 if ( update_cd_mode_ps2_atapi() != 1 )
4902#endif
4903 {
4904 sceCdDecSet(0, 0, 0);
4905 }
4906 cdvdman_init();
4907 g_cdvdman_istruct.m_cd_inited = 1;
4908 }
4909 if ( mode == SCECdINIT )
4910 {
4911 u8 ready_status_tmp;
4912 u8 ready_status;
4913
4914 ready_status_tmp = 0;
4915 VERBOSE_PRINTF(1, "sceCdInit Ready check start.\n");
4916 ready_status = 0;
4917 while ( (ready_status & 0xC0) != 0x40 )
4918 {
4919#ifdef CDVD_VARIANT_XOSD
4920 if ( update_cd_mode_ps2_atapi() == 1 || sceCdGetDiskType() == 6 )
4921 break;
4922 g_cdvdman_istruct.m_field_0DC = 0;
4923 if ( sceCdGetDiskType() == SCECdNODISC )
4924 break;
4925#endif
4926 ready_status = sceCdDiskReady(8);
4927 vDelayThread(10000);
4928 if ( ready_status != ready_status_tmp )
4929 {
4930 ready_status_tmp = ready_status;
4931 VERBOSE_PRINTF(1, "sceCdInit Dev5 Status %x\n", ready_status);
4932 }
4933 // The following Kprintf was added for ioprp300x
4934 VERBOSE_PRINTF(1, "sceCdInit Ready check %x\n", ready_status);
4935 }
4936 VERBOSE_PRINTF(1, "sceCdInit Ready check end.\n");
4937 }
4938 g_cdvdman_istruct.m_wait_flag = 1;
4939 g_cdvdman_istruct.m_scmd_flag = 1;
4940 g_cdvdman_istruct.m_last_error = SCECdErNO;
4941 g_cdvdman_istruct.m_last_read_timeout = 0;
4942 g_cdvdman_spinctl = -1;
4943 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
4944 SetEventFlag(g_ncmd_evfid, 1);
4945 SetEventFlag(g_scmd_evfid, 1);
4946 SetEventFlag(g_sfile_evfid, 1);
4947 return 1;
4948}
4949
4950static int set_prev_command(int cmd, const char *sdata, int sdlen, char *rdata, int rdlen, int check_sef)
4951{
4952 int i;
4953 int delaybackoff;
4954 int j;
4955 u32 efbits;
4956#ifdef CDVD_VARIANT_XOSD
4957 int suspendres;
4958#endif
4959
4960#ifdef CDVD_VARIANT_XOSD
4961 {
4962 int state;
4963
4964 suspendres = CpuSuspendIntr(&state);
4965 CpuResumeIntr(state);
4966 suspendres = QueryIntrContext() || suspendres;
4967 }
4968 VERBOSE_KPRINTF(1, "set_prev_command cmd %02x call\n", cmd);
4969 if ( !suspendres )
4970 {
4971 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
4972 }
4973#endif
4974 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4975 {
4976 // The following Kprintf was added for ioprp300x
4977 VERBOSE_KPRINTF(1, "set_prev_command Double Booking\n");
4978#ifdef CDVD_VARIANT_XOSD
4979 if ( !suspendres )
4980 {
4981 SetEventFlag(g_cdvdman_csys_evfid, 1);
4982 }
4983#endif
4984 return 0;
4985 }
4986 g_cdvdman_istruct.m_scmd = cmd;
4987 g_cdvdman_istruct.m_sdlen = sdlen;
4988 g_cdvdman_istruct.m_rdlen = rdlen;
4989 for ( i = 0; i < sdlen; i += 1 )
4990 {
4991 g_cdvdman_istruct.m_scmd_sd[i] = sdata[i];
4992 }
4993#ifdef CDVD_VARIANT_XOSD
4994 if ( update_cd_mode_ps2_atapi() != 1 )
4995#endif
4996 {
4997 if ( g_cdvdman_istruct.m_wait_flag )
4998 {
4999 g_cdvdman_istruct.m_scmd_flag = 1;
5000 cdvdman_write_scmd(&g_cdvdman_istruct);
5001 }
5002 else if ( QueryIntrContext() )
5003 {
5004 while ( (dmac_ch_get_chcr(3) & 0x1000000) && !g_cdvdman_istruct.m_wait_flag )
5005 {
5006 VERBOSE_KPRINTF(1, "set_prev_command: DMA Wait\n");
5007 }
5008 g_cdvdman_istruct.m_scmd_flag = 1;
5009 cdvdman_write_scmd(&g_cdvdman_istruct);
5010 }
5011 else
5012 {
5013 g_cdvdman_istruct.m_scmd_flag = 0;
5014 }
5015 }
5016#ifdef CDVD_VARIANT_XOSD
5017 else
5018 {
5019 if ( !suspendres )
5020 {
5021 if ( g_cd_atapi_evfid != -1 )
5022 {
5023 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
5024 }
5025 if ( g_adma_evfid != -1 )
5026 {
5027 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5028 }
5029 if ( g_acmd_evfid != -1 )
5030 {
5031 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5032 }
5033 }
5034 {
5035 int state;
5036
5037 CpuSuspendIntr(&state);
5038 set_cdvd_dev5_base_addr_atapi(2);
5039 g_cdvdman_istruct.m_scmd_flag = 1;
5040 VERBOSE_KPRINTF(1, "do_set_prev_command %02x\n", cmd);
5041 cdvdman_write_scmd(&g_cdvdman_istruct);
5042 set_cdvd_dev5_base_addr_atapi(1);
5043 CpuResumeIntr(state);
5044 }
5045 if ( !suspendres )
5046 {
5047 if ( g_acmd_evfid != -1 )
5048 {
5049 SetEventFlag(g_acmd_evfid, 1);
5050 }
5051 if ( g_adma_evfid != -1 )
5052 {
5053 SetEventFlag(g_adma_evfid, 1);
5054 }
5055 if ( g_cd_atapi_evfid != -1 )
5056 {
5057 SetEventFlag(g_cd_atapi_evfid, 3);
5058 }
5059 }
5060 }
5061#endif
5062 delaybackoff = 1;
5063 for ( i = 0; i < 500; i += delaybackoff )
5064 {
5065 if ( g_cdvdman_istruct.m_scmd_flag )
5066 {
5067 for ( j = 0; j < rdlen; j += 1 )
5068 {
5069 rdata[j] = g_cdvdman_istruct.m_scmd_rd[j];
5070 }
5071 if ( check_sef == 1 )
5072 {
5073 vSetEventFlag(g_scmd_evfid, 1);
5074 }
5075#ifdef CDVD_VARIANT_XOSD
5076 VERBOSE_KPRINTF(1, "set_prev_command end :%02x\n", (u8)g_cdvdman_istruct.m_scmd);
5077 if ( !suspendres )
5078 {
5079 SetEventFlag(g_cdvdman_csys_evfid, 1);
5080 }
5081#endif
5082 return (u8)g_cdvdman_istruct.m_scmd;
5083 }
5084 vDelayThread(1000 * delaybackoff);
5085 if ( (i & 1) && delaybackoff < 16 )
5086 {
5087 delaybackoff *= 2;
5088 }
5089 }
5090 g_cdvdman_istruct.m_scmd_flag = 1;
5091 if ( check_sef == 1 )
5092 {
5093 vSetEventFlag(g_scmd_evfid, 1);
5094 }
5095 return 0;
5096}
5097
5098static void cdvdman_write_scmd(cdvdman_internal_struct_t *s)
5099{
5100 int i;
5101 unsigned int j;
5102 unsigned int rdcnt;
5103 char rdptr1[64];
5104 USE_DEV5_MMIO_HWPORT();
5105
5106 // The following Kprintf was added for ioprp300x
5107 VERBOSE_KPRINTF(1, "in:%d out_size:%d \n", (u8)s->m_sdlen, (u8)s->m_rdlen);
5108 // The following Kprintf was added for ioprp300x
5109 VERBOSE_KPRINTF(1, "cmd:%02x pram:%02x\n", (u8)s->m_scmd, (u8)s->m_scmd_sd[0]);
5110 for ( i = 0; i <= 0; i += 1 )
5111 {
5112 int overflowcond;
5113#ifdef CDVD_VARIANT_XOSD
5114 int suspendres;
5115#endif
5116
5117 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5118 {
5119 s->m_scmd_flag = 1;
5120 s->m_scmd = 0;
5121 // The following Kprintf was added for ioprp300x
5122 VERBOSE_KPRINTF(1, "do_set_prev_command BUSY ABNORM END %08x\n", dev5_mmio_hwport->m_dev5_reg_017);
5123 return;
5124 }
5125 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5126 {
5127 ;
5128 }
5129 for ( j = 0; j < (u8)s->m_sdlen; j += 1 )
5130 {
5131 dev5_mmio_hwport->m_dev5_reg_017 = s->m_scmd_sd[j];
5132 }
5133 dev5_mmio_hwport->m_dev5_reg_016 = s->m_scmd;
5134#ifdef CDVD_VARIANT_XOSD
5135 {
5136 int state;
5137 suspendres = CpuSuspendIntr(&state);
5138 CpuResumeIntr(state);
5139 suspendres = QueryIntrContext() || suspendres;
5140 }
5141#endif
5142#ifdef CDVD_VARIANT_XOSD
5143 if ( suspendres )
5144#else
5145 if ( QueryIntrContext() )
5146#endif
5147 {
5148 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
5149 {
5150 if ( j > 12500000 )
5151 {
5152 s->m_scmd_flag = 1;
5153 s->m_scmd = 0;
5154 return;
5155 }
5156 }
5157 }
5158 else
5159 {
5160 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
5161 {
5162 DelayThread(100);
5163 if ( j > 50000 )
5164 {
5165 // The following Kprintf was added for ioprp300x
5166 VERBOSE_KPRINTF(1, "Mecacon Scmd TIMEOUT CMD= %02x\n", (u8)s->m_scmd);
5167 s->m_scmd_flag = 1;
5168 s->m_scmd = 0;
5169 return;
5170 }
5171 }
5172 }
5173 overflowcond = 0;
5174 for ( j = 0; j < (u8)s->m_rdlen; j += 1 )
5175 {
5176 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5177 {
5178 break;
5179 }
5180 rdptr1[j] = dev5_mmio_hwport->m_dev5_reg_018;
5181 }
5182 if ( j >= (u8)s->m_rdlen )
5183 {
5184 overflowcond = 1;
5185 VERBOSE_KPRINTF(1, "Prev Cmd Result Over Flow\n", rdptr1);
5186 }
5187 rdcnt = j;
5188 if ( (!overflowcond && j >= (u8)s->m_rdlen) || s->m_rdlen == 16 )
5189 {
5190 break;
5191 }
5192 VERBOSE_KPRINTF(1, "Prev Cmd Result Illegal Size Try count:%d\n", i);
5193 }
5194 if ( i == 1 )
5195 {
5196 s->m_scmd_flag = 1;
5197 s->m_scmd = 0;
5198 }
5199 else
5200 {
5201 for ( j = 0; j < (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])); j += 1 )
5202 {
5203 s->m_scmd_rd[j] = 0;
5204 }
5205 if ( s->m_rdlen != (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])) )
5206 {
5207 rdcnt = (u8)s->m_rdlen;
5208 }
5209 for ( j = 0; j < rdcnt; j += 1 )
5210 {
5211 s->m_scmd_rd[j] = rdptr1[j];
5212 }
5213 s->m_scmd_flag = 1;
5214 s->m_scmd = 1;
5215 }
5216}
5217
5218#ifdef CDVD_VARIANT_XOSD
5219static int cdvdman_write_scmd_swap_dev5(char cmd, const char *wdata, int sdlen, char *rdata, int rdlen, int check_sef)
5220{
5221 int atapi_check;
5222 int i;
5223 int j;
5224 char rdstart[64];
5225 u32 efbits;
5226 int state;
5227 USE_DEV5_MMIO_HWPORT();
5228
5229 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5230 {
5231 return 0;
5232 }
5233 CpuSuspendIntr(&state);
5234 atapi_check = update_cd_mode_ps2_atapi() == 1;
5235 if ( atapi_check )
5236 {
5237 set_cdvd_dev5_base_addr_atapi(2);
5238 }
5239 for ( i = 0; i <= 0; i += 1 )
5240 {
5241 int cmdresoverflow;
5242
5243 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5244 {
5245 if ( atapi_check )
5246 {
5247 set_cdvd_dev5_base_addr_atapi(1);
5248 }
5249 CpuResumeIntr(state);
5250 if ( check_sef == 1 )
5251 {
5252 vSetEventFlag(g_scmd_evfid, 1);
5253 }
5254 return 0;
5255 }
5256 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5257 {
5258 ;
5259 }
5260 for ( j = 0; j < sdlen; j += 1 )
5261 {
5262 dev5_mmio_hwport->m_dev5_reg_017 = wdata[j];
5263 }
5264 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
5265 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5266 {
5267 ;
5268 }
5269 cmdresoverflow = 0;
5270 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
5271 {
5272 if ( j >= rdlen )
5273 {
5274 cmdresoverflow = 1;
5275 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Over Flow\n");
5276 break;
5277 }
5278 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
5279 }
5280 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
5281 {
5282 break;
5283 }
5284 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Illegal Size Try count:%d\n", i);
5285 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
5286 {
5287 ;
5288 }
5289 for ( j = 0; j < 16 - rdlen; j += 1 )
5290 {
5291 }
5292 }
5293 if ( i == 1 )
5294 {
5295 if ( atapi_check )
5296 {
5297 set_cdvd_dev5_base_addr_atapi(1);
5298 }
5299 CpuResumeIntr(state);
5300 if ( check_sef == 1 )
5301 {
5302 vSetEventFlag(g_scmd_evfid, 1);
5303 }
5304 return 0;
5305 }
5306 for ( j = 0; j < rdlen; j += 1 )
5307 {
5308 rdata[j] = rdstart[j];
5309 }
5310 if ( atapi_check )
5311 {
5312 set_cdvd_dev5_base_addr_atapi(1);
5313 }
5314 CpuResumeIntr(state);
5315 if ( check_sef == 1 )
5316 {
5317 vSetEventFlag(g_scmd_evfid, 1);
5318 }
5319 return 1;
5320}
5321#endif
5322
5323static int cdvdman_send_scmd2(int cmd, const void *sdata, int sdlen, void *rdata, int rdlen, int check_sef)
5324{
5325 int i;
5326 int j;
5327 char rdstart[64];
5328 u32 efbits;
5329 USE_DEV5_MMIO_HWPORT();
5330
5331 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5332 {
5333 return 0;
5334 }
5335 for ( i = 0; i <= 0; i += 1 )
5336 {
5337 int cmdresoverflow;
5338
5339 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5340 {
5341 if ( check_sef == 1 )
5342 {
5343 vSetEventFlag(g_scmd_evfid, 1);
5344 }
5345 return 0;
5346 }
5347 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5348 {
5349 ;
5350 }
5351 for ( j = 0; j < sdlen; j += 1 )
5352 {
5353 dev5_mmio_hwport->m_dev5_reg_017 = ((u8 *)sdata)[j];
5354 }
5355 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
5356 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5357 {
5358#ifndef CDVD_VARIANT_XOSD
5359 DelayThread(100);
5360#endif
5361 }
5362 cmdresoverflow = 0;
5363 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
5364 {
5365 if ( j >= rdlen )
5366 {
5367 cmdresoverflow = 1;
5368 // The following Kprintf was modified for ioprp300x
5369 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Over Flow\n");
5370 break;
5371 }
5372 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
5373 }
5374 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
5375 {
5376 break;
5377 }
5378 // The following Kprintf was modified for ioprp300x
5379 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Illegal Size Try count:%d\n", i);
5380 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
5381 {
5382 ;
5383 }
5384 for ( j = 0; j < 16 - rdlen; j += 1 )
5385 ;
5386 }
5387 if ( i == 1 )
5388 {
5389 if ( check_sef == 1 )
5390 {
5391 vSetEventFlag(g_scmd_evfid, 1);
5392 }
5393 return 0;
5394 }
5395 for ( i = 0; i < rdlen; i += 1 )
5396 {
5397 ((char *)rdata)[i] = rdstart[i];
5398 }
5399 if ( check_sef == 1 )
5400 {
5401 vSetEventFlag(g_scmd_evfid, 1);
5402 }
5403 return 1;
5404}
5405
5406#ifdef CDVD_VARIANT_OSD
5407static unsigned int signal_sema_timeout_callback(void *userdata)
5408{
5409 int sema_id;
5410
5411 sema_id = (int)(u32)(uiptr)userdata;
5412 iSignalSema(sema_id);
5413 return 0;
5414}
5415#endif
5416
5417int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
5418{
5419 int i;
5420
5421#ifdef CDVD_VARIANT_OSD
5422 if ( g_cdvdman_minver_50000 )
5423 {
5424 WaitSema(g_cdvdman_apply_scmd_sema);
5425 }
5426#endif
5427 for ( i = 0; i <= 2500; i += 1 )
5428 {
5429 if ( set_prev_command(cmdNum, (const char *)inBuff, inBuffSize, (char *)outBuff, 16, 1) )
5430 {
5431#ifdef CDVD_VARIANT_OSD
5432 if ( g_cdvdman_minver_50000 )
5433 {
5434 iop_sys_clock_t sysclk;
5435
5436 sysclk.hi = 0;
5437 sysclk.lo = 0x9000;
5438 SetAlarm(&sysclk, signal_sema_timeout_callback, (void *)g_cdvdman_apply_scmd_sema);
5439 }
5440 else
5441#endif
5442 {
5443 DelayThread(2000);
5444 }
5445 return 1;
5446 }
5447 DelayThread(2000);
5448 }
5449 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5450 return 0;
5451}
5452
5453int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
5454{
5455#ifdef CDVD_VARIANT_XOSD
5456 return sceCdApplySCmd(cmdNum, inBuff, inBuffSize, outBuff);
5457#else
5458 int i;
5459
5460 for ( i = 0; i <= 2500; i += 1 )
5461 {
5462 if ( cdvdman_send_scmd2(cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
5463 {
5464 return 1;
5465 }
5466 DelayThread(2000);
5467 }
5468 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5469 return 0;
5470#endif
5471}
5472
5473#ifdef CDVD_VARIANT_OSD
5474int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
5475{
5476 int i;
5477
5478 for ( i = 0; i <= 2500; i += 1 )
5479 {
5480 DelayThread(2000);
5481 if ( set_prev_command((u8)cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
5482 {
5483 DelayThread(2000);
5484 return 1;
5485 }
5486 }
5487 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5488 return 0;
5489}
5490#endif
5491
5492int sceCdBreak(void)
5493{
5494 u32 efbits;
5495 int state;
5496 int oldstate;
5497 USE_DEV5_MMIO_HWPORT();
5498
5499 if ( PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5500 {
5501 return 0;
5502 }
5503 CpuSuspendIntr(&state);
5504 // The following Kprintf was modified for ioprp300x
5505 VERBOSE_KPRINTF(
5506 1,
5507 "Break call: read2_flg= %d func= %d lsn= %d csec= %d nsec= %d %rsec= %d addr= %p waitflg= %d, DriveIntrReq= %d "
5508 "stmflg= %d recover= %d\n",
5509 g_cdvdman_istruct.m_read2_flag,
5510 g_cdvdman_cmdfunc,
5511 g_cdvdman_istruct.m_cdvdman_lsn,
5512 g_cdvdman_istruct.m_cdvdman_csec,
5513 g_cdvdman_istruct.m_cdvdman_nsec,
5514 g_cdvdman_istruct.m_cdvdman_rsec,
5515 g_cdvdman_istruct.m_read_buf,
5516 g_cdvdman_istruct.m_wait_flag,
5517 g_cdvdman_istruct.m_drive_interupt_request,
5518 g_cdvdman_istruct.m_stream_flag,
5519 g_cdvdman_istruct.m_recover_status);
5520 if ( g_cdvdman_istruct.m_last_read_timeout )
5521 {
5522 g_cdvdman_istruct.m_read2_flag = 0;
5523 }
5524 g_cdvdman_istruct.m_last_error = SCECdErABRT;
5525 g_cdvdman_istruct.m_thread_id = GetThreadId();
5526 g_cdvdman_istruct.m_break_cdvdfsv_readchain = 1;
5527 if ( g_cdvdman_istruct.m_dec_state )
5528 {
5529 g_cdvdman_istruct.m_dec_shift = 0;
5530 g_cdvdman_istruct.m_check_version = 0;
5531 g_cdvdman_istruct.m_dec_state = 0;
5532 sceCdDecSet(0, 0, 0);
5533 }
5534 g_cdvdman_istruct.m_recover_status = 0;
5535 if ( QueryIntrContext() )
5536 {
5537 iSetEventFlag(g_cdvdman_intr_evfid, 0x29);
5538 iCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5539 }
5540 else
5541 {
5542 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
5543 CancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5544 }
5545 if ( !g_cdvdman_istruct.m_wait_flag || g_cdvdman_istruct.m_last_read_timeout )
5546 {
5547 // The following direct register access was replaced with call for ioprp300x
5548 if ( (sceCdDiskReady(8) & 0xC0) == 0x40 )
5549 {
5550 VERBOSE_KPRINTF(1, "cdvd: NonInter END\n");
5551 g_cdvdman_istruct.m_wait_flag = 1;
5552 }
5553 g_cdvdman_last_cmdfunc = g_cdvdman_cmdfunc;
5554 g_cdvdman_cmdfunc = SCECdFuncBreak;
5555 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5556 if ( g_cdvdman_istruct.m_last_read_timeout )
5557 {
5558 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
5559 }
5560 g_cdvdman_istruct.m_drive_interupt_request = 0;
5561 VERBOSE_KPRINTF(1, "cdvd: Abort command On\n");
5562 }
5563 vSetEventFlag(g_ncmd_evfid, 1);
5564 CpuResumeIntr(state);
5565 return 1;
5566}
5567
5568static unsigned int ncmd_timeout_alarm_cb(void *userdata)
5569{
5570 iop_sys_clock_t *sys_clock;
5571
5572 sys_clock = (iop_sys_clock_t *)userdata;
5573 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
5574 sys_clock->lo = 0;
5575 return 0;
5576}
5577
5578static int intrh_dma_3(void *userdata)
5579{
5580 int dmacbres;
5581 int oldstate;
5583
5584 s = (cdvdman_internal_struct_t *)userdata;
5585 s->m_dma3_param.m_dma3_msectors -= s->m_dma3_param.m_dma3_csectors;
5586 // The following Kprintf was added for ioprp300x
5587 VERBOSE_KPRINTF(
5588 1,
5589 "_sceCdDmaIntr wk %d: func_num: %d nsec %d cnt %d cdid:%08x\n",
5590 s->m_wait_flag,
5591 g_cdvdman_cmdfunc,
5592 s->m_dma3_param.m_dma3_msectors,
5593 s->m_cdvdman_dma3sec,
5594 &g_cdvdman_istruct);
5595 dmacbres = s->m_dma3_param.m_dma3_callback ? s->m_dma3_param.m_dma3_callback() : 1;
5596 s->m_cdvdman_dma3sec += s->m_dma3_param.m_dma3_csectors;
5597 s->m_dma3_param.m_dma3_csectors = ((u32)s->m_read_chunk > (u32)s->m_dma3_param.m_dma3_msectors) ?
5598 (u32)s->m_dma3_param.m_dma3_msectors :
5599 (u32)s->m_read_chunk;
5600 if ( dmacbres )
5601 {
5602 if ( s->m_dma3_param.m_dma3_msectors )
5603 {
5604 dmac_ch_set_chcr(3, 0);
5605 dmac_ch_get_chcr(3);
5606 dmac_ch_set_madr(3, (u32)s->m_dma3_param.m_dma3_maddress);
5607 dmac_ch_set_bcr(
5608 3,
5609 ((s->m_dma3_param.m_dma3_blkcount * s->m_dma3_param.m_dma3_csectors) << 16) | s->m_dma3_param.m_dma3_blkwords);
5610 dmac_ch_set_chcr(3, 0x41000200);
5611 dmac_ch_get_chcr(3);
5612 iClearEventFlag(g_cdvdman_intr_evfid, ~0x20);
5613 }
5614 else
5615 {
5616 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
5617 iSetEventFlag(g_cdvdman_intr_evfid, 0x20);
5618 }
5619 }
5620 if ( !s->m_dma3_param.m_dma3_msectors && s->m_drive_interupt_request )
5621 {
5622 cdvdman_intr_cb(s);
5623 s->m_drive_interupt_request = 0;
5624 }
5625 return 1;
5626}
5627
5628static int cdvdman_setdma3(cdvdman_dma3_parameter_t *dma3_param)
5629{
5630 USE_DEV5_MMIO_HWPORT();
5631
5632 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
5633 {
5634 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5635 }
5636 g_cdvdman_istruct.m_drive_interupt_request = 0;
5637 g_cdvdman_istruct.m_dma3_param.m_dma3_blkwords = dma3_param->m_dma3_blkwords;
5638 g_cdvdman_istruct.m_dma3_param.m_dma3_blkcount = dma3_param->m_dma3_blkcount;
5639 g_cdvdman_istruct.m_dma3_param.m_dma3_maddress = dma3_param->m_dma3_maddress;
5640 g_cdvdman_istruct.m_dma3_param.m_dma3_callback = dma3_param->m_dma3_callback;
5641 g_cdvdman_istruct.m_dma3_param.m_dma3_csectors = dma3_param->m_dma3_csectors;
5642 g_cdvdman_istruct.m_dma3_param.m_cdvdreg_howto = dma3_param->m_cdvdreg_howto;
5643 g_cdvdman_istruct.m_dma3_param.m_dma3_msectors = dma3_param->m_dma3_msectors;
5644 g_cdvdman_istruct.m_cdvdman_dma3sec = 0;
5645 dmac_ch_set_chcr(3, 0);
5646 dmac_ch_get_chcr(3);
5647 if ( dma3_param->m_dma3_csectors )
5648 {
5649 vClearEventFlag(g_cdvdman_intr_evfid, ~0x20);
5650 EnableIntr(IOP_IRQ_DMA_CDVD);
5651 }
5652 dev5_mmio_hwport->m_dev5_reg_006 = dma3_param->m_cdvdreg_howto;
5653 dmac_ch_set_madr(3, (u32)dma3_param->m_dma3_maddress);
5654 dmac_ch_set_bcr(
5655 3,
5656 (dma3_param->m_dma3_blkcount * (dma3_param->m_dma3_csectors ? dma3_param->m_dma3_csectors : 1)) << 16
5657 | dma3_param->m_dma3_blkwords);
5658 dmac_ch_set_chcr(3, 0x41000200);
5659 return dmac_ch_get_chcr(3);
5660}
5661
5662#ifdef CDVD_VARIANT_XOSD
5663static int update_cd_mode_ps2_atapi(void)
5664{
5665 int is_intr_context;
5666 int saved_cd_mode_ps2_atapi;
5667 int state;
5668
5669 is_intr_context = !QueryIntrContext();
5670 if ( is_intr_context )
5671 {
5672 CpuSuspendIntr(&state);
5673 }
5674 saved_cd_mode_ps2_atapi = g_cdvdman_istruct.m_cd_mode_ps2_atapi;
5675 if ( saved_cd_mode_ps2_atapi == 1 )
5676 {
5677 if ( !(*g_cdvdreg_bf801460 & 2) || (unsigned int)GetBaseAddress(5) != (unsigned int)0xBF410000 )
5678 {
5679 set_cdvd_dev5_base_addr_atapi(1);
5680 }
5681 }
5682 else
5683 {
5684 if ( (*g_cdvdreg_bf801460 & 2) || (unsigned int)GetBaseAddress(5) != (unsigned int)0x1F402000 )
5685 {
5686 set_cdvd_dev5_base_addr_atapi(2);
5687 }
5688 }
5689 if ( is_intr_context )
5690 {
5691 CpuResumeIntr(state);
5692 }
5693 return saved_cd_mode_ps2_atapi;
5694}
5695#endif
5696
5697#ifdef CDVD_VARIANT_XOSD
5698static int set_cdvd_dev5_base_addr_atapi(int mode)
5699{
5700 int is_intr_context;
5701 int state;
5702
5703 is_intr_context = !QueryIntrContext();
5704 if ( is_intr_context )
5705 {
5706 CpuSuspendIntr(&state);
5707 }
5708 if ( mode == 1 )
5709 {
5710 SetBaseAddress(5, 0xBF410000);
5711 VERBOSE_KPRINTF(1, "DEV5-addr : 0x%08lx\n", GetBaseAddress(5));
5712 SetDelay(5, 0xEF101043);
5713 VERBOSE_KPRINTF(1, "DEV5-dely : 0x%08lx\n", GetDelay(5));
5714 *g_cdvdreg_bf801464 |= 0xC;
5715 *g_cdvdreg_bf801460 |= 0x40;
5716 *g_cdvdreg_bf801460 |= 2;
5717 }
5718 else
5719 {
5720 SetBaseAddress(5, 0x1F402000);
5721 VERBOSE_KPRINTF(1, "DEV5-addr : 0x%08lx\n", GetBaseAddress(5));
5722 SetDelay(5, 0x6F060011);
5723 VERBOSE_KPRINTF(1, "DEV5-dely : 0x%08lx\n", GetDelay(5));
5724 *g_cdvdreg_bf801460 &= ~2;
5725 *g_cdvdreg_bf801460 &= ~0x40;
5726 *g_cdvdreg_bf801464 &= 0xF3;
5727 }
5728 if ( is_intr_context )
5729 {
5730 CpuResumeIntr(state);
5731 }
5732 return 1;
5733}
5734#endif
5735
5736#ifdef CDVD_VARIANT_XOSD
5737static int cdvdman_change_drive(int mode)
5738{
5739 ClearEventFlag(g_cdvdman_csys_evfid, ~1);
5740 if ( mode == 1 )
5741 {
5742 VERBOSE_KPRINTF(1, "Init Go SCECdChgWriDrv\n");
5743 ClearEventFlag(g_fio_fsv_evfid, ~1);
5744 ClearEventFlag(g_sfile_evfid, ~1);
5745 ClearEventFlag(g_scmd_evfid, ~1);
5746 ClearEventFlag(g_ncmd_evfid, ~1);
5747 set_cdvd_dev5_base_addr_atapi(1);
5748 if ( g_cd_atapi_evfid != -1 )
5749 {
5750 SetEventFlag(g_cd_atapi_evfid, 3);
5751 }
5752 if ( g_adma_evfid != -1 )
5753 {
5754 SetEventFlag(g_adma_evfid, 1);
5755 }
5756 if ( g_acmd_evfid != -1 )
5757 {
5758 SetEventFlag(g_acmd_evfid, 1);
5759 }
5760 SetEventFlag(g_scmd_evfid, 1);
5761 VERBOSE_KPRINTF(1, "Init Go SCECdChgWriDrv End.\n");
5762 SetEventFlag(g_fio_fsv_evfid, 1);
5763 }
5764 else
5765 {
5766 VERBOSE_KPRINTF(1, "Init Go SCECdChgPs2Drv\n");
5767 ClearEventFlag(g_scmd_evfid, ~1);
5768 if ( g_acmd_evfid != -1 )
5769 {
5770 ClearEventFlag(g_acmd_evfid, ~1);
5771 }
5772 if ( g_adma_evfid != -1 )
5773 {
5774 ClearEventFlag(g_adma_evfid, ~1);
5775 }
5776 if ( g_cd_atapi_evfid != -1 )
5777 {
5778 ClearEventFlag(g_cd_atapi_evfid, ~3);
5779 }
5780 set_cdvd_dev5_base_addr_atapi(mode);
5781 SetEventFlag(g_ncmd_evfid, 1);
5782 SetEventFlag(g_scmd_evfid, 1);
5783 SetEventFlag(g_sfile_evfid, 1);
5784 SetEventFlag(g_fio_fsv_evfid, 1);
5785 VERBOSE_KPRINTF(1, "Init Go SCECdChgPs2Drv End.\n");
5786 }
5787 SetEventFlag(g_cdvdman_csys_evfid, 1);
5788 return 1;
5789}
5790#endif
5791
5792#ifdef CDVD_VARIANT_XOSD
5793// cppcheck-suppress funcArgNamesDifferent
5794int sceCdChgSys(u32 use_writer_drive)
5795{
5796 int current_mode;
5797 u32 efbits;
5798 USE_DEV5_MMIO_HWPORT();
5799
5800 VERBOSE_KPRINTF(1, "sceCdChgSys(%d) start.\n", use_writer_drive);
5801 if ( QueryIntrContext() )
5802 {
5803 return 0;
5804 }
5805 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5806 current_mode = update_cd_mode_ps2_atapi();
5807 VERBOSE_KPRINTF(
5808 1, "sceCdChgSys %d call mode:%d->%d\n", use_writer_drive, current_mode, g_cdvdman_istruct.m_cd_mode_ps2_atapi);
5809 if ( !use_writer_drive )
5810 {
5811 g_cdvdman_istruct.m_cd_mode_ps2_atapi = current_mode;
5812 }
5813 if (
5814 use_writer_drive
5815 && (use_writer_drive != (u32)current_mode || g_cdvdman_istruct.m_cd_mode_ps2_atapi != current_mode) )
5816 {
5817 int disc_type;
5818
5819 if ( use_writer_drive == 1 )
5820 {
5821 VERBOSE_KPRINTF(1, "Go SCECdChgWriDrv\n");
5822 VERBOSE_KPRINTF(1, "fio_fsv_evfid\n");
5823 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5824 VERBOSE_KPRINTF(1, "sfile_evfid\n");
5825 WaitEventFlag(g_sfile_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5826 VERBOSE_KPRINTF(1, "sceCdSync\n");
5827 sceCdSync(0);
5828 VERBOSE_KPRINTF(1, "scmd_evfid\n");
5829 WaitEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5830 VERBOSE_KPRINTF(1, "ncmd_evfid\n");
5831 WaitEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5832 set_cdvd_dev5_base_addr_atapi(2);
5833 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5834 if ( g_cdvdman_vernotxxx1x )
5835 {
5836 if ( (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5837 {
5838 g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open = 1;
5839 }
5840 if (
5841 (!(dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen))
5842 || (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5843 {
5844 int last_err;
5845
5846 last_err = 2;
5847 while ( last_err != SCECdErNO && last_err != SCECdErABRT )
5848 {
5849 VERBOSE_KPRINTF(1, "GO->Atapi sceCdChgSpdlCtrl Call %d\n", 0);
5850 while ( !sceCdChgSpdlCtrl(0) )
5851 {
5852 DelayThread(16000);
5853 }
5854 sceCdSync(3);
5855 last_err = sceCdGetError();
5856 if ( last_err != SCECdErNO )
5857 {
5858 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl ERR 0x%02x\n", last_err);
5859 DelayThread(250000);
5860 }
5861 }
5862 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl OK\n", last_err);
5863 }
5864 }
5865 set_cdvd_dev5_base_addr_atapi(1);
5866 g_cdvdman_istruct.m_cd_mode_ps2_atapi = 1;
5867 if (
5868 g_cdvdman_vernotxxx1x && disc_type != SCECdNODISC && g_cdvdman_istruct.m_chgsys_callback_next_disktype_last
5869 && g_cdvdman_istruct.m_chgsys_callback )
5870 {
5871 int i;
5872
5873 for ( i = 0;
5874 i < 10 && g_cdvdman_istruct.m_chgsys_callback(&g_cdvdman_istruct.m_chgsys_callback_next_disktype, 1);
5875 i += 1 )
5876 {
5877 DelayThread(16000);
5878 }
5879 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = SCECdNODISC;
5880 }
5881 if ( g_cd_atapi_evfid != -1 )
5882 {
5883 SetEventFlag(g_cd_atapi_evfid, 3);
5884 }
5885 if ( g_adma_evfid != -1 )
5886 {
5887 SetEventFlag(g_adma_evfid, 1);
5888 }
5889 if ( g_acmd_evfid != -1 )
5890 {
5891 SetEventFlag(g_acmd_evfid, 1);
5892 }
5893 SetEventFlag(g_scmd_evfid, 1);
5894 SetEventFlag(g_fio_fsv_evfid, 1);
5895 VERBOSE_KPRINTF(1, "Go SCECdChgWriDrv End.\n");
5896 }
5897 else
5898 {
5899 VERBOSE_KPRINTF(1, "Go SCECdChgPs2Drv\n");
5900 VERBOSE_KPRINTF(1, "scmd_evfid\n");
5901 WaitEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5902 if ( g_acmd_evfid != -1 )
5903 {
5904 VERBOSE_KPRINTF(1, "g_acmd_evfid Wait\n");
5905 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5906 }
5907 if ( g_adma_evfid != -1 )
5908 {
5909 VERBOSE_KPRINTF(1, "g_adma_evfid Wait\n");
5910 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5911 }
5912 if ( g_cd_atapi_evfid != -1 )
5913 {
5914 VERBOSE_KPRINTF(1, "g_cd_atapi_evfid Wait\n");
5915 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
5916 }
5917 VERBOSE_KPRINTF(1, "evflg Ok\n");
5918 set_cdvd_dev5_base_addr_atapi(1);
5919 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5920 if ( g_cdvdman_vernotxxx1x )
5921 {
5922 set_cdvd_dev5_base_addr_atapi(2);
5923 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5924 set_cdvd_dev5_base_addr_atapi(1);
5925 VERBOSE_KPRINTF(1, "GO->PS2 STOP ATAPI SPINDL\n");
5926 if ( disc_type == 6 && g_cdvdman_istruct.m_chgsys_callback )
5927 {
5928 int i;
5929
5930 for ( i = 0;
5931 i < 10 && g_cdvdman_istruct.m_chgsys_callback(&g_cdvdman_istruct.m_chgsys_callback_next_disktype, 0);
5932 i += 1 )
5933 {
5934 DelayThread(16000);
5935 }
5936 if ( i == 10 )
5937 {
5938 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5939 }
5940 VERBOSE_KPRINTF(1, "Atapi Set -> Dragon Media %d\n", g_cdvdman_istruct.m_chgsys_callback_next_disktype);
5941 if ( g_cdvdman_istruct.m_chgsys_callback_next_disktype == 256 )
5942 {
5943 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = g_cdvdman_istruct.m_chgsys_callback_next_disktype;
5944 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5945 }
5946 }
5947 }
5948 set_cdvd_dev5_base_addr_atapi(use_writer_drive);
5949 g_cdvdman_istruct.m_cd_mode_ps2_atapi = use_writer_drive;
5950 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5951 if ( g_cdvdman_vernotxxx1x )
5952 {
5953 if (
5954 ((dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen))
5955 || (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5956 {
5957 int last_err;
5958
5959 last_err = 2;
5960 while ( last_err != SCECdErNO && last_err != SCECdErABRT && last_err != SCECdErPRM )
5961 {
5962 if ( (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5963 {
5964 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCT;
5965 }
5966 VERBOSE_KPRINTF(
5967 1,
5968 "GO->DRAGON sceCdChgSpdlCtrl Call %d Ps2MediaType %02x\n",
5969 g_cdvdman_istruct.m_chgsys_callback_next_disktype,
5970 disc_type);
5971 while ( !sceCdChgSpdlCtrl(g_cdvdman_istruct.m_chgsys_callback_next_disktype) )
5972 {
5973 DelayThread(16000);
5974 }
5975 sceCdSync(3);
5976 last_err = sceCdGetError();
5977 if ( last_err != SCECdErNO )
5978 {
5979 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl ERR 0x%02x\n", last_err);
5980 DelayThread(250000);
5981 }
5982 }
5983 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl OK\n");
5984 }
5985 }
5986 else
5987 {
5988 VERBOSE_KPRINTF(1, " -> Ps2 May be No media %08x\n", disc_type);
5989 }
5990 SetEventFlag(g_ncmd_evfid, 1);
5991 SetEventFlag(g_scmd_evfid, 1);
5992 SetEventFlag(g_sfile_evfid, 1);
5993 SetEventFlag(g_fio_fsv_evfid, 1);
5994 VERBOSE_KPRINTF(1, "Go SCECdChgPs2Drv End.\n");
5995 }
5996 }
5997 SetEventFlag(g_cdvdman_csys_evfid, 1);
5998 return current_mode;
5999}
6000#endif
6001
6002static int
6003cdvdman_send_ncmd(int ncmd, const void *ndata, int ndlen, int func, cdvdman_dma3_parameter_t *dma3_param, int check_cb)
6004{
6005 int i;
6006 u32 efbits;
6007 USE_DEV5_MMIO_HWPORT();
6008
6009 if ( check_cb == 1 && PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6010 {
6011 return -1;
6012 }
6013 if (
6014 // The following direct register access was replaced with call for ioprp300x
6015 (sceCdDiskReady(8) & 0xC0) != 0x40 || !g_cdvdman_istruct.m_wait_flag
6016 || !(g_cdvdman_istruct.m_read2_flag != 1 || ncmd == 8) || !(g_cdvdman_istruct.m_read2_flag != 2 || ncmd == 6) )
6017 {
6018 if ( check_cb == 1 )
6019 {
6020 vSetEventFlag(g_ncmd_evfid, 1);
6021 }
6022 // The following direct register access was replaced with call for ioprp300x
6023 VERBOSE_KPRINTF(1, "set_cd_commnad Error\tstat %02x\n", (u8)sceCdDiskReady(8));
6024 return -1;
6025 }
6026 g_cdvdman_iocache = 0;
6027 if ( dma3_param )
6028 {
6029 cdvdman_setdma3(dma3_param);
6030 }
6031 g_cdvdman_cmdfunc = func;
6032 // The following call to sceCdGetDiskType was inlined
6033 if (
6034 !g_cdvdman_minver_10700 && g_cdvdman_ncmd == 0x06 && ncmd && ncmd != g_cdvdman_ncmd && ncmd != 0x07 && ncmd != 0x0E
6035 && ncmd != 0x08
6036#ifdef CDVD_VARIANT_XOSD
6037 && ncmd != 0x0C
6038#endif
6039 && (sceCdGetDiskType() != SCECdCDDA || ncmd == 0x03) )
6040 {
6041 g_cdvdman_ncmd_timeout.hi = 0;
6042 g_cdvdman_ncmd_timeout.lo = 0x6978000;
6043 vSetAlarm(&g_cdvdman_ncmd_timeout, ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
6044 while ( dev5_mmio_hwport->m_dev5_reg_00A != SCECdStatPause )
6045 {
6046 VERBOSE_KPRINTF(1, "Read Pause 1 chk status 0x%02x\n", dev5_mmio_hwport->m_dev5_reg_00A);
6047 if ( !g_cdvdman_ncmd_timeout.lo )
6048 {
6049 g_cdvdman_ncmd = ncmd;
6050 if ( check_cb == 1 )
6051 {
6052 vSetEventFlag(g_ncmd_evfid, 1);
6053 }
6054 KPRINTF("Time Out Pause WAIT set_cd_commnad\n");
6055 return -1;
6056 }
6057 vDelayThread(1000);
6058 }
6059 vCancelAlarm(ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
6060 }
6061 g_cdvdman_ncmd = ncmd;
6062 if ( g_cdvdman_istruct.m_dec_state )
6063 {
6064 sceCdDecSet(!!g_cdvdman_istruct.m_dec_shift, 1, g_cdvdman_istruct.m_dec_shift);
6065 }
6066 g_cdvdman_istruct.m_last_read_timeout = 0;
6067 g_cdvdman_istruct.m_cdvdman_command = ncmd;
6068 g_cdvdman_istruct.m_last_error = SCECdErNO;
6069 g_cdvdman_istruct.m_wait_flag = 0;
6070 g_cdvdman_istruct.m_thread_id = GetThreadId();
6071 if ( QueryIntrContext() )
6072 {
6073 iClearEventFlag(g_cdvdman_intr_evfid, ~1);
6074 }
6075 else
6076 {
6077 ClearEventFlag(g_cdvdman_intr_evfid, ~1);
6078 }
6079 for ( i = 0; i < ndlen; i += 1 )
6080 {
6081 dev5_mmio_hwport->m_dev5_reg_005 = ((u8 *)ndata)[i];
6082 }
6083 dev5_mmio_hwport->m_dev5_reg_004 = ncmd;
6084 if ( check_cb == 1 )
6085 {
6086 vSetEventFlag(g_ncmd_evfid, 1);
6087 }
6088 return 0;
6089}
6090
6091int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
6092{
6093 VERBOSE_KPRINTF(1, "Apply NCmd call cmd= 0x%02x\n", cmdNum);
6094 while ( cdvdman_send_ncmd(cmdNum, inBuff, inBuffSize, 0, 0, 1) < 0 )
6095 {
6096 vDelayThread(2000);
6097 }
6098 sceCdSync(4);
6099 return 1;
6100}
6101
6102int sceCdCheckCmd(void)
6103{
6104 return g_cdvdman_istruct.m_wait_flag;
6105}
6106
6107static int cdvdman_mediactl(int code)
6108{
6109 int reg_00B_tmp_1;
6110 int retval;
6111 u32 efbits;
6112 char rdata[1];
6113#ifndef CDVD_VARIANT_XOSD
6114 USE_DEV5_MMIO_HWPORT();
6115#endif
6116
6117 rdata[0] = 0;
6118 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6119 {
6120 return 0;
6121 }
6122#ifdef CDVD_VARIANT_XOSD
6123 reg_00B_tmp_1 = get_cdvd_register(0x0B) & SCECdStatShellOpen;
6124#else
6125 reg_00B_tmp_1 = dev5_mmio_hwport->m_dev5_reg_00B & SCECdStatShellOpen;
6126#endif
6127 if ( reg_00B_tmp_1 == g_cdvdman_chmedia )
6128 {
6129 retval = 0;
6130 if ( g_cdvdman_chflags[code] )
6131 {
6132 g_cdvdman_chflags[code] = 0;
6133 retval = 1;
6134 }
6135 }
6136 else
6137 {
6138 unsigned int i;
6139
6140 for ( i = 0; i < (sizeof(g_cdvdman_chflags) / sizeof(g_cdvdman_chflags[0])); i += 1 )
6141 {
6142 g_cdvdman_chflags[i] = i != (unsigned int)code;
6143 }
6144 retval = 1;
6145 }
6146#ifdef CDVD_VARIANT_XOSD
6147 if ( ((get_cdvd_register(0x0A)) & SCECdStatShellOpen) != reg_00B_tmp_1 )
6148#else
6149 if ( ((dev5_mmio_hwport->m_dev5_reg_00A) & SCECdStatShellOpen) != reg_00B_tmp_1 )
6150#endif
6151 {
6152 while ( !set_prev_command(0x05, NULL, 0, rdata, sizeof(rdata), 0) || rdata[0] )
6153 {
6154 vDelayThread(4000);
6155 }
6156 }
6157#ifdef CDVD_VARIANT_XOSD
6158 g_cdvdman_chmedia = get_cdvd_register(0x0B) & 1;
6159#else
6160 g_cdvdman_chmedia = dev5_mmio_hwport->m_dev5_reg_00B & SCECdStatShellOpen;
6161#endif
6162 vSetEventFlag(g_scmd_evfid, 1);
6163 return retval;
6164}
6165
6166int sceCdGetError(void)
6167{
6168 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
6169 {
6170 VERBOSE_KPRINTF(1, "sceCdGetError: 0x%02x\n", (u8)g_cdvdman_istruct.m_last_error);
6171 }
6172 return (u8)g_cdvdman_istruct.m_last_error;
6173}
6174
6175#ifdef DEAD_CODE
6176int cdvdman_get_last_command(void)
6177{
6178 return (u8)g_cdvdman_istruct.m_cdvdman_command;
6179}
6180#endif
6181
6182int sceCdNop(void)
6183{
6184 return cdvdman_send_ncmd(0x00, NULL, 0, 0, 0, 1) >= 0;
6185}
6186
6187#ifdef DEAD_CODE
6188int cdvdman_ncmd_sender_01(void)
6189{
6190 return cdvdman_send_ncmd(0x01, NULL, 0, 0, 0, 1) >= 0;
6191}
6192#endif
6193
6194#ifndef CDVD_VARIANT_XOSD
6195static int cdvdman_ncmd_sender_06(void)
6196{
6197 int i;
6198 cdvdman_dma3_parameter_t dma3_param;
6199 char ndata[11];
6200
6201 // The following call to sceCdGetDiskType was inlined
6202 if ( sceCdGetDiskType() == SCECdNODISC )
6203 {
6204 return 1;
6205 }
6206 for ( i = 0; i < 48; i += 8 )
6207 {
6208 // The following Kprintf was removed for ioprp300x
6209 KPRINTF("CMD_READP call\n");
6210 ndata[0] = i + 17;
6211 ndata[3] = 0;
6212 ndata[2] = 0;
6213 ndata[1] = 0;
6214 ndata[4] = 8;
6215 ndata[7] = 0;
6216 ndata[6] = 0;
6217 ndata[5] = 0;
6218 ndata[8] = 0;
6219 ndata[9] = 1;
6220 ndata[10] = 0;
6221 dma3_param.m_cdvdreg_howto = 128;
6222 dma3_param.m_dma3_blkwords = 32;
6223 dma3_param.m_dma3_blkcount = 128;
6224 dma3_param.m_dma3_csectors = 0;
6225 dma3_param.m_dma3_msectors = 0;
6226 dma3_param.m_dma3_callback = 0;
6227 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
6228 if ( cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 5, &dma3_param, 1) < 0 )
6229 {
6230 return 0;
6231 }
6232 sceCdSync(3);
6233 }
6234 return 1;
6235}
6236#endif
6237
6238int sceCdStandby(void)
6239{
6240 cdvdman_dma3_parameter_t dma3_param;
6241 char ndata[11];
6242
6243#ifdef CDVD_VARIANT_XOSD
6244 switch ( get_disk_type_ex() )
6245#else
6246 // The following call to sceCdGetDiskType was inlined
6247 switch ( sceCdGetDiskType() )
6248#endif
6249 {
6250 case SCECdPSCD:
6251 case SCECdPSCDDA:
6252 case SCECdPS2CD:
6253 case SCECdPS2CDDA:
6254 case SCECdPS2DVD:
6255 ndata[0] = 16;
6256 ndata[4] = 1;
6257 ndata[9] = 1;
6258 dma3_param.m_cdvdreg_howto = 128;
6259 dma3_param.m_dma3_blkwords = 32;
6260 dma3_param.m_dma3_blkcount = 16;
6261 ndata[3] = 0;
6262 ndata[2] = 0;
6263 ndata[1] = 0;
6264 ndata[7] = 0;
6265 ndata[6] = 0;
6266 ndata[5] = 0;
6267 ndata[8] = 0;
6268 ndata[10] = 0;
6269 dma3_param.m_dma3_csectors = 0;
6270 dma3_param.m_dma3_msectors = 0;
6271 dma3_param.m_dma3_callback = 0;
6272 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
6273 return cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 5, &dma3_param, 1) >= 0;
6274 default:
6275 return cdvdman_send_ncmd(0x02, NULL, 0, 5, 0, 1) >= 0;
6276 }
6277}
6278
6279int sceCdStop(void)
6280{
6281 return cdvdman_send_ncmd(0x03, NULL, 0, 6, 0, 1) >= 0;
6282}
6283
6284int sceCdPause(void)
6285{
6286 return cdvdman_send_ncmd(0x04, NULL, 0, 7, 0, 1) >= 0;
6287}
6288
6289#ifdef DEAD_CODE
6290int cdvdman_ncmd_sender_0B(void)
6291{
6292 char ndata[1];
6293
6294 ndata[0] = 1;
6295 return cdvdman_send_ncmd(0x0B, ndata, sizeof(ndata), 0, 0, 1) >= 0;
6296}
6297#endif
6298
6299static unsigned int readtoc_timeout_alarm_cb(void *userdata)
6300{
6301 iop_sys_clock_t *sys_clock;
6302 USE_DEV5_MMIO_HWPORT();
6303
6304 sys_clock = (iop_sys_clock_t *)userdata;
6305 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
6306 dev5_mmio_hwport->m_dev5_reg_007 = 1;
6307 sys_clock->lo = 0;
6308 return 0;
6309}
6310
6311static int cdvdman_readtoc(u8 *toc, int param, int func)
6312{
6313 int last_err;
6314 cdvdman_dma3_parameter_t dma3_param;
6315 iop_sys_clock_t sysclk;
6316 char ndata[1];
6317
6318#ifdef CDVD_VARIANT_XOSD
6319 switch ( get_disk_type_ex() )
6320#else
6321 // The following call to sceCdGetDiskType was inlined
6322 switch ( sceCdGetDiskType() )
6323#endif
6324 {
6325 case SCECdPS2DVD:
6326 case SCECdDVDVR:
6327 case SCECdDVDV:
6328 dma3_param.m_cdvdreg_howto = 132;
6329 dma3_param.m_dma3_blkwords = 4;
6330 dma3_param.m_dma3_blkcount = 129;
6331 dma3_param.m_dma3_maddress = toc;
6332 dma3_param.m_dma3_msectors = 0;
6333 dma3_param.m_dma3_csectors = 0;
6334 dma3_param.m_dma3_callback = 0;
6335 ndata[0] = param;
6336 break;
6337 case SCECdPSCD:
6338 case SCECdPSCDDA:
6339 case SCECdPS2CD:
6340 case SCECdPS2CDDA:
6341 case SCECdCDDA:
6342 dma3_param.m_cdvdreg_howto = 128;
6343 dma3_param.m_dma3_blkwords = 32;
6344 dma3_param.m_dma3_blkcount = 8;
6345 dma3_param.m_dma3_maddress = toc;
6346 dma3_param.m_dma3_msectors = 0;
6347 dma3_param.m_dma3_csectors = 0;
6348 dma3_param.m_dma3_callback = 0;
6349 ndata[0] = 0;
6350 break;
6351 default:
6352 return 0;
6353 }
6354 if ( cdvdman_send_ncmd(0x09, ndata, sizeof(ndata), func, &dma3_param, 1) < 0 )
6355 {
6356 return 0;
6357 }
6358 sysclk.hi = 0;
6359 sysclk.lo = 0x15F90000;
6360 vSetAlarm(&sysclk, readtoc_timeout_alarm_cb, &sysclk);
6361 sceCdSync(3);
6362 vCancelAlarm(readtoc_timeout_alarm_cb, &sysclk);
6363 last_err = sceCdGetError();
6364 if ( g_cdvdman_minver_10700 && !sceCdPause() )
6365 {
6366 return 0;
6367 }
6368 sceCdSync(3);
6369 return last_err == SCECdErNO;
6370}
6371
6372static int cdvdman_gettoc(u8 *toc)
6373{
6374 // The following Kprintf was added for ioprp300x
6375 VERBOSE_KPRINTF(1, "sceCdReadToc() call 0x%p\n", toc);
6376 return cdvdman_readtoc(toc, 0, 3);
6377}
6378
6379#ifdef CDVD_VARIANT_OSD
6380int sceCdGetToc2(u8 *toc, int param)
6381{
6382 cdvdman_dma3_parameter_t dma3_param;
6383 char ndata[1];
6384
6385 dma3_param.m_cdvdreg_howto = 140;
6386 dma3_param.m_dma3_blkwords = 12;
6387 dma3_param.m_dma3_blkcount = 43;
6388 dma3_param.m_dma3_maddress = toc;
6389 dma3_param.m_dma3_msectors = 0;
6390 dma3_param.m_dma3_csectors = 0;
6391 dma3_param.m_dma3_callback = 0;
6392 ndata[0] = param;
6393 return cdvdman_send_ncmd(0x09, ndata, sizeof(ndata), 0, &dma3_param, 1) >= 0;
6394}
6395#endif
6396
6397u32 sceCdGetReadPos(void)
6398{
6399 int sector_sizes[4];
6400
6401 sector_sizes[0] = 0x800;
6402 sector_sizes[1] = 0x918;
6403 sector_sizes[2] = 0x924;
6404 if ( g_cdvdman_istruct.m_recover_status && g_cdvdman_istruct.m_recover_status != 3 )
6405 {
6406 return 0;
6407 }
6408 if ( g_cdvdman_cmdfunc == SCECdFuncReadCDDA || g_cdvdman_cmdfunc == 12 )
6409 {
6410 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
6411 }
6412 if ( g_cdvdman_istruct.m_read2_flag )
6413 {
6414 return g_cdvdman_readptr * sector_sizes[g_cdvdman_istruct.m_cdvdman_pattern];
6415 }
6416 if ( g_cdvdman_cmdfunc == SCECdFuncRead )
6417 {
6418 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
6419 }
6420 return 0;
6421}
6422
6423static int cdvdman_speedctl(u32 spindlctrl, int dvdflag, u32 maxlsn)
6424{
6425 u32 maxlsn_chk;
6426
6427 switch ( spindlctrl )
6428 {
6429 case SCECdSpinStm:
6430 return dvdflag ? 2 : 4;
6431 case SCECdSpinNom:
6432 if ( !dvdflag )
6433 {
6434 return 133;
6435 }
6436 if ( g_cdvdman_minver_10700 )
6437 {
6438 return 131;
6439 }
6440#ifdef CDVD_VARIANT_OSD
6441 // From DVD Player 3.11
6442 maxlsn_chk = 0x1C9000;
6443#else
6444 maxlsn_chk = 0x128000;
6445#endif
6446 if ( g_cdvdman_istruct.m_opo_or_para )
6447 {
6448 maxlsn -= (maxlsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn) ? g_cdvdman_istruct.m_layer_1_lsn : 0;
6449#ifdef CDVD_VARIANT_OSD
6450 // From DVD Player 3.11
6451 maxlsn_chk = 0x197000;
6452#else
6453 maxlsn_chk = 0x165000;
6454#endif
6455 }
6456 if ( maxlsn >= maxlsn_chk )
6457 {
6458 VERBOSE_KPRINTF(1, "Kprob Spd D lsn= %d\n", maxlsn);
6459 return 130;
6460 }
6461 return 133;
6462 case SCECdSpinX1:
6463 case 0xE:
6464 return 1;
6465 case SCECdSpinX2:
6466 return 2;
6467 case SCECdSpinX4:
6468 return dvdflag ? 2 : 131;
6469 case SCECdSpinX12:
6470 return dvdflag ? 3 : 4;
6471 case SCECdSpinNm2:
6472 return 64;
6473 case 0xC:
6474 return dvdflag ? 4 : 2;
6475 case 0xF:
6476 return 130;
6477 case 0x10:
6478 return dvdflag ? 130 : 131;
6479 case 0x11:
6480 return dvdflag ? 130 : 132;
6481 case 0x12:
6482 return dvdflag ? 1 : 131;
6483 case SCECdSpinMx:
6484 return dvdflag ? 3 : 5;
6485 default:
6486 return dvdflag ? 131 : 133;
6487 }
6488}
6489
6490static int cdvdman_isdvd(void)
6491{
6492 // The following call to sceCdGetDiskType was inlined
6493#ifdef CDVD_VARIANT_XOSD
6494 switch ( get_disk_type_ex() )
6495#else
6496 switch ( sceCdGetDiskType() )
6497#endif
6498 {
6499 case SCECdPSCD:
6500 case SCECdPSCDDA:
6501 case SCECdPS2CD:
6502 case SCECdPS2CDDA:
6503 case SCECdCDDA:
6504 g_cdvdman_istruct.m_tray_is_open = 1;
6505 return 0;
6506 case SCECdPS2DVD:
6507 case SCECdDVDVR:
6508 case SCECdDVDV:
6509 g_cdvdman_istruct.m_tray_is_open = 1;
6510 return 1;
6511 default:
6512 return 0;
6513 }
6514}
6515
6516static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func)
6517{
6518 cdvdman_dma3_parameter_t dma3_param;
6519 char ndata[11];
6520
6521 g_cdvdman_readbuf = buf;
6522 VERBOSE_KPRINTF(1, "sceCdRead0_Rty Lsn:%d nsec:%d dintrnsec %d func %08x\n", lsn, nsec, dintrsec, func);
6523 *(u32 *)ndata = lsn;
6524 *(u32 *)&ndata[4] = nsec;
6525 ndata[8] = mode->trycount;
6526 ndata[9] = cdvdman_speedctl(mode->spindlctrl, cdvdman_isdvd(), lsn + nsec);
6527 dma3_param.m_dma3_csectors = dintrsec;
6528 dma3_param.m_dma3_callback = (int (*)(void))func;
6529 dma3_param.m_dma3_msectors = nsec;
6530 dma3_param.m_dma3_maddress = buf;
6531 dma3_param.m_dma3_blkcount = (!(u16)dintrsec) ? nsec : 1;
6532 switch ( ncmd )
6533 {
6534 case 0x06:
6535 ndata[10] = mode->datapattern;
6536 switch ( mode->datapattern )
6537 {
6538 case SCECdSecS2328:
6539 dma3_param.m_dma3_blkwords = 6;
6540 dma3_param.m_dma3_blkcount *= 97;
6541 dma3_param.m_cdvdreg_howto = 134;
6542 break;
6543 case SCECdSecS2340:
6544 dma3_param.m_dma3_blkwords = 15;
6545 dma3_param.m_dma3_blkcount *= 39;
6546 dma3_param.m_cdvdreg_howto = 143;
6547 break;
6548 case SCECdSecS2048:
6549 default:
6550 dma3_param.m_dma3_blkwords = 32;
6551 dma3_param.m_dma3_blkcount *= 16;
6552 dma3_param.m_cdvdreg_howto = 128;
6553 break;
6554 }
6555 break;
6556 case 0x08:
6557 dma3_param.m_dma3_blkwords = 12;
6558 dma3_param.m_dma3_blkcount *= 43;
6559 dma3_param.m_cdvdreg_howto = 140;
6560 ndata[10] = 0;
6561 break;
6562 default:
6563 return 0;
6564 }
6565 return cdvdman_send_ncmd(ncmd, ndata, sizeof(ndata), ncmd == 0x06 ? 1 : 14, &dma3_param, 0) >= 0;
6566}
6567
6568int sceCdRead0(u32 lsn, u32 sectors, void *buffer, sceCdRMode *mode, int csec, void *callback)
6569{
6570 cdvdman_dma3_parameter_t dma3_param;
6571 char ndata[11];
6572 u32 efbits;
6573
6574 if ( PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6575 {
6576 return 0;
6577 }
6578 VERBOSE_KPRINTF(
6579 1,
6580 "DVD/CD sceCdRead0 sec %d num %d spin %d trycnt %d dptn %d adr %08x\n",
6581 lsn,
6582 sectors,
6583 mode->spindlctrl,
6584 mode->trycount,
6585 mode->datapattern,
6586 buffer);
6587 g_cdvdman_readbuf = buffer;
6588 dma3_param.m_dma3_csectors = (csec && (sectors < (u32)csec)) ? sectors : (u32)csec;
6589 dma3_param.m_dma3_callback = (int (*)(void))callback;
6590 dma3_param.m_dma3_msectors = sectors;
6591 dma3_param.m_dma3_blkcount = (!csec) ? sectors : 1;
6592 switch ( mode->datapattern )
6593 {
6594 case SCECdSecS2328:
6595 dma3_param.m_dma3_blkwords = 6;
6596 dma3_param.m_dma3_blkcount *= 97;
6597 dma3_param.m_cdvdreg_howto = 134;
6598 break;
6599 case SCECdSecS2340:
6600 dma3_param.m_dma3_blkwords = 15;
6601 dma3_param.m_dma3_blkcount *= 39;
6602 dma3_param.m_cdvdreg_howto = 143;
6603 break;
6604 case SCECdSecS2048:
6605 default:
6606 dma3_param.m_dma3_blkwords = 32;
6607 dma3_param.m_dma3_blkcount *= 16;
6608 dma3_param.m_cdvdreg_howto = 128;
6609 break;
6610 }
6611 // The following call to sceCdGetDiskType was inlined
6612#ifdef CDVD_VARIANT_OSD
6613 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
6614#else
6615 switch ( sceCdGetDiskType() )
6616 {
6617 case SCECdPSCD:
6618 case SCECdPSCDDA:
6619 case SCECdPS2CD:
6620 case SCECdPS2CDDA:
6621 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
6622 {
6623 vSetEventFlag(g_ncmd_evfid, 1);
6624 return 0;
6625 }
6626 g_cdvdman_istruct.m_dvd_flag = 0;
6627 break;
6628 case SCECdPS2DVD:
6629 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
6630 {
6631 vSetEventFlag(g_ncmd_evfid, 1);
6632 return 0;
6633 }
6634 g_cdvdman_istruct.m_dvd_flag = 1;
6635 break;
6636 default:
6637 vSetEventFlag(g_ncmd_evfid, 1);
6638 return 0;
6639 }
6640#endif
6641 g_cdvdman_istruct.m_read_mode = *mode;
6642 g_cdvdman_istruct.m_read_callback = callback;
6643 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
6644 g_cdvdman_istruct.m_read_lsn = lsn;
6645 g_cdvdman_istruct.m_read_sectors = sectors;
6646 *(u32 *)ndata = lsn;
6647 *(u32 *)&ndata[4] = sectors;
6648 ndata[8] = mode->trycount;
6649 ndata[9] = cdvdman_speedctl(mode->spindlctrl, g_cdvdman_istruct.m_dvd_flag, lsn + sectors);
6650 g_cdvdman_istruct.m_read_buf = buffer;
6651 ndata[10] = mode->datapattern;
6652 dma3_param.m_dma3_maddress = buffer;
6653 VERBOSE_KPRINTF(1, "Read Command call\n");
6654 if ( cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 1, &dma3_param, 0) < 0 )
6655 {
6656 vSetEventFlag(g_ncmd_evfid, 1);
6657 return 0;
6658 }
6659 vSetEventFlag(g_ncmd_evfid, 1);
6660 return 1;
6661}
6662
6663static int read_cdvd_cb(cdvdman_internal_struct_t *common)
6664{
6665 int sblock;
6666 int i;
6667 u32 cdreadlsn;
6668 int syncdec_res_1;
6669 sceCdlLOCCD cdrloc;
6670
6671 sblock = 0;
6672 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
6673 {
6674 char syncdec_res_4;
6675 int errlsn;
6676
6677 syncdec_res_4 = 0;
6678 if ( common->m_read2_flag == 3 )
6679 {
6680 sblock = 0x924;
6681 cdrloc.minute = cdvdman_syncdec(
6682 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
6683 cdrloc.second = cdvdman_syncdec(
6684 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1]);
6685 cdrloc.sector = cdvdman_syncdec(
6686 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2]);
6687 cdreadlsn = sceCdPosToInt(&cdrloc);
6688 }
6689 else
6690 {
6691 sblock = 0x810;
6692 syncdec_res_1 = (u8)cdvdman_syncdec(
6693 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 3]);
6694 syncdec_res_1 +=
6695 (u8)cdvdman_syncdec(
6696 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2])
6697 << 8;
6698 syncdec_res_1 +=
6699 (u8)cdvdman_syncdec(
6700 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1])
6701 << 16;
6702 syncdec_res_4 = cdvdman_syncdec(
6703 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
6704 if ( !common->m_cdvdman_dma3sec && !common->m_interupt_read_state )
6705 {
6706 common->m_interupt_read_state = (syncdec_res_4 & 0xC) | (((syncdec_res_4 & 0xC) && i) ? 0x80 : 0);
6707 }
6708 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);
6709 }
6710 errlsn = common->m_cdvdman_lsn + common->m_cdvdman_csec + common->m_cdvdman_dma3sec + i;
6711 if ( cdreadlsn != (u32)errlsn )
6712 {
6713 VERBOSE_KPRINTF(
6714 1, "Read_IOP Sector_ID error lsn= %d readlsn= %d layer= %d\n", errlsn, cdreadlsn, (syncdec_res_4 & 1));
6715 break;
6716 }
6717 }
6718 if ( i == common->m_dma3_param.m_dma3_csectors )
6719 {
6720 unsigned int size;
6721
6722 size = 0;
6723 switch ( common->m_cdvdman_pattern )
6724 {
6725 case 0:
6726 size = 0x800;
6727 break;
6728 case 1:
6729 default:
6730 size = 0x918;
6731 break;
6732 case 2:
6733 optimized_memcpy(
6734 &((char *)(common->m_cdvdman_rbuffer))[0x924 * common->m_cdvdman_dma3sec],
6735 (const char *)g_cdvdman_ptoc,
6736 0x924 * i);
6737 break;
6738 }
6739 if ( size )
6740 {
6741 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
6742 {
6743 optimized_memcpy(
6744 &((char *)(common->m_cdvdman_rbuffer))[(common->m_cdvdman_dma3sec + i) * size],
6745 (const char *)&g_cdvdman_ptoc[12 + (i * sblock)],
6746 size);
6747 }
6748 }
6749 g_cdvdman_readptr = common->m_cdvdman_csec + common->m_cdvdman_dma3sec;
6750 }
6751 else
6752 {
6753 common->m_sync_error += 1;
6754 }
6755 return 1;
6756}
6757
6758static int cdvdman_read(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int decflag, int shift, int ef1, int ef2)
6759{
6760 int read_res;
6761 int state;
6762 int scres_unused;
6763 int dvd;
6764 int ready;
6765
6766 dvd = cdvdman_isdvd();
6767 if ( dvd )
6768 {
6769 if ( !DvdDual_infochk() )
6770 {
6771 if ( ef1 )
6772 {
6773 vSetEventFlag(ef1, ef2);
6774 }
6775 return 0;
6776 }
6777 lsn = sceCdLsnDualChg(lsn);
6778 }
6779 else if ( mode->datapattern == SCECdSecS2328 || (g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state) )
6780 {
6781 int read0_res;
6782
6783 if ( g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state && mode->spindlctrl == SCECdSpinNom )
6784 {
6785 mode->spindlctrl = SCECdSpinStm;
6786 }
6787 CpuSuspendIntr(&state);
6788 read0_res = sceCdRead0(lsn, sectors, buf, mode, 0, 0);
6789 if ( ef1 )
6790 {
6791 vSetEventFlag(ef1, ef2);
6792 }
6793 CpuResumeIntr(state);
6794 return read0_res;
6795 }
6796 CpuSuspendIntr(&state);
6797 ready = sceCdDiskReady(8) & 0xC0;
6798 if ( ready != 0x40 || g_cdvdman_istruct.m_read2_flag )
6799 {
6800 // The following Kprintf was modified for ioprp300x
6801 VERBOSE_KPRINTF(
6802 1,
6803 "sceCdRead: Double Booking error r2f= %d waf= %d rdy= %02x\n",
6804 g_cdvdman_istruct.m_read2_flag,
6805 g_cdvdman_istruct.m_wait_flag,
6806 ready);
6807 if ( ef1 )
6808 {
6809 vSetEventFlag(ef1, ef2);
6810 }
6811 CpuResumeIntr(state);
6812 return 0;
6813 }
6814 if ( decflag )
6815 {
6816 g_cdvdman_istruct.m_dec_shift = shift;
6817 g_cdvdman_istruct.m_dec_state = 1;
6818 }
6819 g_cdvdman_readbuf = buf;
6820 g_cdvdman_readptr = 0;
6821 g_cdvdman_istruct.m_cdvdman_lsn = lsn;
6822 g_cdvdman_istruct.m_cdvdman_csec = 0;
6823 g_cdvdman_istruct.m_cdvdman_nsec = sectors;
6824 g_cdvdman_istruct.m_cdvdman_rbuffer = (int)buf;
6825 g_cdvdman_istruct.m_cdvdman_pattern = dvd ? SCECdSecS2048 : mode->datapattern;
6826 g_cdvdman_istruct.m_cdvdman_cdrmode.trycount = mode->trycount;
6827 g_cdvdman_istruct.m_cdvdman_cdrmode.spindlctrl = mode->spindlctrl;
6828 g_cdvdman_istruct.m_cdvdman_cdrmode.datapattern = dvd ? SCECdSecS2048 : SCECdSecS2340;
6829 g_cdvdman_istruct.m_read2_flag = dvd ? 1 : 3;
6830 g_cdvdman_istruct.m_sync_error = 0;
6831 g_cdvdman_istruct.m_interupt_read_state = 0;
6832 g_cdvdman_istruct.m_cdvdman_rsec = (sectors >= 0x41) ? (((lsn & 0xF)) ? (0x10 - (lsn & 0xF)) : 0x40) : sectors;
6833 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6834 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6835 vSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6836 read_res = (dvd ? sceCdRV : sceCdRead0)(
6837 lsn,
6838 g_cdvdman_istruct.m_cdvdman_rsec,
6839 g_cdvdman_ptoc,
6840 dvd ? mode : &g_cdvdman_istruct.m_cdvdman_cdrmode,
6841 g_cdvdman_cache_sector_count,
6842 read_cdvd_cb);
6843 if ( !read_res )
6844 {
6845 g_cdvdman_istruct.m_last_error = SCECdErREADCFR;
6846 g_cdvdman_istruct.m_cdvdman_rsec = 0;
6847 g_cdvdman_istruct.m_read2_flag = 0;
6848 if ( g_cdvdman_istruct.m_dec_state )
6849 {
6850 g_cdvdman_istruct.m_dec_shift = 0;
6851 g_cdvdman_istruct.m_check_version = 0;
6852 g_cdvdman_istruct.m_dec_state = 0;
6853 sceCdDecSet(0, 0, 0);
6854 }
6855 vCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6856 }
6857 if ( ef1 )
6858 {
6859 vSetEventFlag(ef1, ef2);
6860 }
6861 CpuResumeIntr(state);
6862 return !!read_res;
6863}
6864
6865int sceCdRE(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
6866{
6867 return cdvdman_read(lsn, sectors, buf, mode, 0, 0, 0, 0);
6868}
6869
6870int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
6871{
6872 iop_event_info_t efinfo;
6873 int state;
6874
6875 // Unofficial: initialize to 0
6876 memset(&efinfo, 0, sizeof(efinfo));
6877 CpuSuspendIntr(&state);
6878 vReferEventFlagStatus(g_fio_fsv_evfid, &efinfo);
6879 if ( !(efinfo.currBits & 1) )
6880 {
6881 CpuResumeIntr(state);
6882 return 0;
6883 }
6884 vClearEventFlag(g_fio_fsv_evfid, ~1);
6885 CpuResumeIntr(state);
6886 return cdvdman_read(lbn, sectors, buffer, mode, 0, 0, g_fio_fsv_evfid, 1);
6887}
6888
6889static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data)
6890{
6891 return decflag ? ((u8)(((u8)data << (shift % 8)) | ((u8)data >> (8 - shift % 8))) ^ (u8)decxor) : (u8)data;
6892}
6893
6894static void Read2intrCDVD(int read2_flag)
6895{
6896 iCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6897 if ( g_cdvdman_istruct.m_last_error != SCECdErNO || g_cdvdman_retries >= 5 )
6898 {
6899 if ( g_cdvdman_istruct.m_last_error == SCECdErNO )
6900 {
6901 g_cdvdman_istruct.m_last_error = SCECdErREADCF;
6902 }
6903 g_cdvdman_istruct.m_read2_flag = 0;
6904 g_cdvdman_retries = 0;
6905 g_cdvdman_rtindex = 0;
6906 g_cdvdman_readptr = 0;
6907 if ( g_cdvdman_istruct.m_dec_state )
6908 {
6909 g_cdvdman_istruct.m_dec_shift = 0;
6910 g_cdvdman_istruct.m_check_version = 0;
6911 g_cdvdman_istruct.m_dec_state = 0;
6912 }
6913 g_cdvdman_istruct.m_interupt_read_state = 0;
6914 }
6915 else if ( !g_cdvdman_istruct.m_interupt_read_state || g_cdvdman_istruct.m_cdvdman_csec )
6916 {
6917 int scres_unused;
6918
6919 g_cdvdman_istruct.m_interupt_read_state = 0;
6920 if ( g_cdvdman_istruct.m_sync_error )
6921 {
6922 u32 lsn_tmp;
6923
6924 if ( !g_cdvdman_rtindex )
6925 {
6926 g_cdvdman_rtindex = 3;
6927 g_cdvdman_retries += 1;
6928 }
6929 g_cdvdman_istruct.m_sync_error = 0;
6930 lsn_tmp = g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec;
6931 if ( lsn_tmp >= 0x30 )
6932 {
6933 lsn_tmp -= 0x10 * (g_cdvdman_rtindex - 1);
6934 }
6935 else
6936 {
6937 lsn_tmp += 0x10 * (g_cdvdman_rtindex - 1);
6938 }
6939 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
6940 lsn_tmp,
6941 g_cdvdman_istruct.m_cdvdman_rsec,
6942 g_cdvdman_ptoc,
6943 &g_cdvdman_istruct.m_cdvdman_cdrmode,
6944 g_cdvdman_cache_sector_count,
6945 read_cdvd_cb) )
6946 {
6947 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6948 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6949 iSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6950 }
6951 else
6952 {
6953 VERBOSE_KPRINTF(1, "Retry Read Fatal Error\n");
6954 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
6955 g_cdvdman_istruct.m_read2_flag = 0;
6956 g_cdvdman_retries = 0;
6957 g_cdvdman_rtindex = 0;
6958 g_cdvdman_readptr = 0;
6959 if ( g_cdvdman_istruct.m_dec_state )
6960 {
6961 g_cdvdman_istruct.m_dec_shift = 0;
6962 g_cdvdman_istruct.m_check_version = 0;
6963 g_cdvdman_istruct.m_dec_state = 0;
6964 }
6965 }
6966 g_cdvdman_rtindex -= !!g_cdvdman_rtindex;
6967 }
6968 else
6969 {
6970 int cdsectorsz;
6971
6972 g_cdvdman_retries = 0;
6973 switch ( g_cdvdman_istruct.m_cdvdman_pattern )
6974 {
6975 case 0:
6976 cdsectorsz = 0x800;
6977 break;
6978 case 1:
6979 default:
6980 cdsectorsz = 0x918;
6981 break;
6982 case 2:
6983 cdsectorsz = 0x924;
6984 break;
6985 }
6986 g_cdvdman_istruct.m_cdvdman_rbuffer += cdsectorsz * g_cdvdman_istruct.m_cdvdman_rsec;
6987 g_cdvdman_istruct.m_cdvdman_csec += g_cdvdman_istruct.m_cdvdman_rsec;
6988 if ( (unsigned int)g_cdvdman_istruct.m_cdvdman_csec < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec )
6989 {
6990 g_cdvdman_istruct.m_cdvdman_rsec =
6991 ((unsigned int)(g_cdvdman_istruct.m_cdvdman_csec + 0x40) < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec) ?
6992 0x40 :
6993 (g_cdvdman_istruct.m_cdvdman_nsec - g_cdvdman_istruct.m_cdvdman_csec);
6994 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
6995 g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec,
6996 g_cdvdman_istruct.m_cdvdman_rsec,
6997 g_cdvdman_ptoc,
6998 &g_cdvdman_istruct.m_cdvdman_cdrmode,
6999 g_cdvdman_cache_sector_count,
7000 read_cdvd_cb) )
7001 {
7002 g_cdvdman_read_alarm_cb_timeout.hi = 0;
7003 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
7004 iSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
7005 }
7006 else
7007 {
7008 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
7009 g_cdvdman_istruct.m_read2_flag = 0;
7010 g_cdvdman_readptr = 0;
7011 if ( g_cdvdman_istruct.m_dec_state )
7012 {
7013 g_cdvdman_istruct.m_dec_shift = 0;
7014 g_cdvdman_istruct.m_check_version = 0;
7015 g_cdvdman_istruct.m_dec_state = 0;
7016 }
7017 }
7018 }
7019 else
7020 {
7021 g_cdvdman_istruct.m_read2_flag = 0;
7022 g_cdvdman_readptr = 0;
7023 if ( g_cdvdman_istruct.m_dec_state )
7024 {
7025 g_cdvdman_istruct.m_dec_shift = 0;
7026 g_cdvdman_istruct.m_check_version = 0;
7027 g_cdvdman_istruct.m_dec_state = 0;
7028 }
7029 }
7030 }
7031 }
7032 else
7033 {
7034 g_cdvdman_istruct.m_last_error = ((g_cdvdman_istruct.m_interupt_read_state & 0x80)) ? SCECdErREADCF : SCECdErIPI;
7035 g_cdvdman_istruct.m_interupt_read_state = 0;
7036 VERBOSE_KPRINTF(1, "IPIerr emu Hit Dummy Err %02x\n", (u8)g_cdvdman_istruct.m_last_error);
7037 g_cdvdman_istruct.m_read2_flag = 0;
7038 g_cdvdman_retries = 0;
7039 g_cdvdman_rtindex = 0;
7040 g_cdvdman_readptr = 0;
7041 if ( g_cdvdman_istruct.m_dec_state )
7042 {
7043 g_cdvdman_istruct.m_dec_shift = 0;
7044 g_cdvdman_istruct.m_check_version = 0;
7045 g_cdvdman_istruct.m_dec_state = 0;
7046 }
7047 }
7048}
7049
7051{
7052 (void)tag;
7053 (void)mode;
7054
7055 return 0;
7056}
7057
7058static int cdvdman_readfull(u32 lsn, u32 sectors, void *buf, const sceCdRMode *mode, int flag)
7059{
7060 cdvdman_dma3_parameter_t dma3_param;
7061 char ndata[11];
7062
7063 VERBOSE_KPRINTF(1, "lsn:%d nsec:%d buf:% cmdmode:%d\n", lsn, sectors, buf, flag);
7064 // The following Kprintf was added for ioprp300x
7065 VERBOSE_KPRINTF(1, "DA Read lsn= %d nsec= %d datapattern= %d\n", lsn, sectors, mode->datapattern);
7066 g_cdvdman_readbuf = buf;
7067#ifdef CDVD_VARIANT_XOSD
7068 dma3_param.m_dma3_csectors = sectors;
7069 dma3_param.m_dma3_msectors = (u16)sectors;
7070#else
7071 dma3_param.m_dma3_csectors = 0;
7072 dma3_param.m_dma3_msectors = 0;
7073#endif
7074 dma3_param.m_dma3_callback = 0;
7075 dma3_param.m_dma3_blkcount = sectors;
7076 switch ( mode->datapattern )
7077 {
7078 case SCECdSecS2328:
7079 dma3_param.m_dma3_blkwords = 8;
7080 dma3_param.m_dma3_blkcount *= 74;
7081 dma3_param.m_cdvdreg_howto = 136;
7082 break;
7083 case SCECdSecS2340:
7084 dma3_param.m_dma3_blkwords = 12;
7085 dma3_param.m_dma3_blkcount *= 51;
7086 dma3_param.m_cdvdreg_howto = 140;
7087 break;
7088 case SCECdSecS2048:
7089 default:
7090 dma3_param.m_dma3_blkwords = 12;
7091 dma3_param.m_dma3_blkcount *= 49;
7092 dma3_param.m_cdvdreg_howto = 140;
7093 break;
7094 }
7095 // The following call to sceCdGetDiskType() was inlined
7096#ifdef CDVD_VARIANT_XOSD
7097 switch ( get_disk_type_ex() )
7098#else
7099 switch ( sceCdGetDiskType() )
7100#endif
7101 {
7102 case SCECdPSCDDA:
7103 case SCECdPS2CDDA:
7104 case SCECdCDDA:
7105 break;
7106 default:
7107 return 0;
7108 }
7109#ifndef CDVD_VARIANT_OSD
7110 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
7111 {
7112 return 0;
7113 }
7114#endif
7115 *(u32 *)ndata = lsn;
7116 *(u32 *)&ndata[4] = sectors;
7117 ndata[8] = mode->trycount;
7118 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 0, lsn + sectors);
7119 dma3_param.m_dma3_maddress = buf;
7120 ndata[10] = mode->datapattern;
7121 return cdvdman_send_ncmd((!flag) ? 0x07 : 0x0E, ndata, sizeof(ndata), (!flag) ? 2 : 12, &dma3_param, 1) >= 0;
7122}
7123
7124// cppcheck-suppress constParameterPointer
7125int sceCdReadCDDA(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
7126{
7127 return cdvdman_readfull(lbn, sectors, buffer, mode, 0);
7128}
7129
7130#ifdef CDVD_VARIANT_OSD
7131// cppcheck-suppress constParameterPointer
7132int sceCdReadFull(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
7133{
7134 return g_cdvdman_minver_20800 ? cdvdman_readfull(lsn, sectors, buf, mode, 1) :
7135 cdvdman_readfull(lsn, sectors, buf, mode, 0);
7136}
7137#endif
7138
7139int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
7140{
7141 cdvdman_dma3_parameter_t dma3_param;
7142 char ndata[11];
7143 u32 efbits;
7144
7145 if (
7146#ifdef CDVD_VARIANT_XOSD
7147 get_disk_type_ex() != SCECdPS2DVD
7148#else
7149 // The following call to sceCdGetDiskType was inlined
7151#endif
7152#ifndef CDVD_VARIANT_OSD
7153 || (g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF)
7154#endif
7155 || (PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND) )
7156 {
7157 return 0;
7158 }
7159 VERBOSE_KPRINTF(
7160 1, "RV read: sec %d num %d spin %d trycnt %d addr %08x\n", lsn, sectors, mode->spindlctrl, mode->trycount, buf);
7161 g_cdvdman_readbuf = buf;
7162 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
7163 g_cdvdman_istruct.m_read_mode = *mode;
7164 g_cdvdman_istruct.m_read_lsn = lsn;
7165 g_cdvdman_istruct.m_read_sectors = sectors;
7166 *(u32 *)ndata = lsn;
7167 *(u32 *)&ndata[4] = sectors;
7168 ndata[8] = mode->trycount;
7169 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 1, lsn + sectors);
7170 ndata[10] = 0;
7171 dma3_param.m_dma3_csectors = (arg5 && (sectors < (u32)arg5)) ? sectors : (u32)arg5;
7172 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
7173 dma3_param.m_cdvdreg_howto = 140;
7174 dma3_param.m_dma3_blkwords = 12;
7175 g_cdvdman_istruct.m_read_buf = buf;
7176 dma3_param.m_dma3_blkcount = (!arg5) ? sectors : 1;
7177 dma3_param.m_dma3_blkcount *= 43;
7178 dma3_param.m_dma3_msectors = sectors;
7179 dma3_param.m_dma3_callback = (int (*)(void))cb;
7180 g_cdvdman_istruct.m_read_callback = cb;
7181 dma3_param.m_dma3_maddress = buf;
7182 if ( cdvdman_send_ncmd(0x08, ndata, sizeof(ndata), 14, &dma3_param, 0) < 0 )
7183 {
7184 vSetEventFlag(g_ncmd_evfid, 1);
7185 return 0;
7186 }
7187 vSetEventFlag(g_ncmd_evfid, 1);
7188 return 1;
7189}
7190
7191#ifdef CDVD_VARIANT_OSD
7192// cppcheck-suppress constParameterPointer
7193int sceCdReadDVDV(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
7194{
7195 cdvdman_dma3_parameter_t dma3_param;
7196 char ndata[11];
7197
7198#ifdef CDVD_VARIANT_XOSD
7199 switch ( get_disk_type_ex() )
7200#else
7201 // The following call to sceCdGetDiskType was inlined
7202 switch ( sceCdGetDiskType() )
7203#endif
7204 {
7205 case SCECdPS2DVD:
7206 case SCECdDVDVR:
7207 case SCECdDVDV:
7208 break;
7209 default:
7210 return 0;
7211 }
7212 switch ( mode->spindlctrl )
7213 {
7214 case SCECdSpinMax:
7215 case SCECdSpinX4:
7216 ndata[9] = 3;
7217 break;
7218 case SCECdSpinX1:
7219 ndata[9] = 1;
7220 break;
7221 case SCECdSpinX2:
7222 case 0xC:
7223 ndata[9] = 4;
7224 break;
7225 case 0xA:
7226 ndata[9] = 0x40;
7227 break;
7228 case 0xB:
7229 ndata[9] = 2;
7230 break;
7231 default:
7232 ndata[9] = 0x83;
7233 break;
7234 }
7235 *(u32 *)ndata = lbn;
7236 *(u32 *)&ndata[4] = sectors;
7237 dma3_param.m_cdvdreg_howto = 140;
7238 dma3_param.m_dma3_blkwords = 12;
7239 dma3_param.m_dma3_blkcount = 43 * sectors;
7240 ndata[10] = 0;
7241 dma3_param.m_dma3_maddress = buffer;
7242 dma3_param.m_dma3_msectors = 0;
7243 dma3_param.m_dma3_csectors = 0;
7244 dma3_param.m_dma3_callback = 0;
7245 ndata[8] = mode->trycount;
7246 return cdvdman_send_ncmd(0x08, ndata, sizeof(ndata), 9, &dma3_param, 1) >= 0;
7247}
7248#endif
7249
7250int sceCdSeek(u32 lbn)
7251{
7252 char ndata[4];
7253
7254 *(u32 *)ndata = lbn;
7255 if ( cdvdman_isdvd() )
7256 {
7257 if ( !DvdDual_infochk() )
7258 {
7259 return 0;
7260 }
7261 *(u32 *)ndata = sceCdLsnDualChg(lbn);
7262 }
7263 return cdvdman_send_ncmd(0x05, ndata, sizeof(ndata), 4, 0, 1) >= 0;
7264}
7265
7266#ifdef CDVD_VARIANT_XOSD
7267static unsigned int sceCdChgSpdlCtrl(int mode)
7268{
7269 unsigned int retval;
7270 char ndata[1];
7271
7272 ndata[0] = mode;
7273 retval = ~cdvdman_send_ncmd(0x0F, ndata, sizeof(ndata), 0xF, 0, 0);
7274 VERBOSE_KPRINTF(1, "Called sceCdChgSpdlCtrl mode:%d ret= %d\n", mode & 0xFF, retval >> 31);
7275 return retval >> 31;
7276}
7277#endif
7278
7279// cppcheck-suppress funcArgNamesDifferent
7280int sceCdRI(u8 *buffer, u32 *status)
7281{
7282 int retval;
7283 char rdata[9];
7284
7285 retval = set_prev_command(0x12, NULL, 0, rdata, sizeof(rdata), 1);
7286 *status = rdata[0];
7287 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7288 return retval;
7289}
7290
7291int sceCdRM(char *buffer, u32 *status)
7292{
7293 int retval;
7294 int cmd_tmp2;
7295 char rdata[9];
7296 char wdata[1];
7297 u32 efbits;
7298
7299 *status = SCECdErNO;
7300 if ( sceCdMV((u8 *)rdata, status) != 1 || (unsigned int)(rdata[3] | (rdata[2] << 8) | (rdata[1] << 16)) < 0x10500 )
7301 {
7302 strcpy(buffer, "M_NAME_UNKNOWN");
7303 buffer[15] = 0;
7304 *status |= 0x40;
7305 return 1;
7306 }
7307 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
7308 {
7309 return 0;
7310 }
7311 DelayThread(2000);
7312 wdata[0] = 0;
7313 retval = set_prev_command(0x17, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
7314 *status = rdata[0];
7315 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7316 DelayThread(2000);
7317 wdata[0] = 8;
7318 cmd_tmp2 = set_prev_command(0x17, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
7319 *status |= rdata[0];
7320 memcpy(&buffer[8], &rdata[1], sizeof(rdata) - 1);
7321 vSetEventFlag(g_scmd_evfid, 1);
7322 return retval ? (!!cmd_tmp2) : 0;
7323}
7324
7325#ifdef CDVD_VARIANT_OSD
7326// Not implemented XOSD or DVD Player 3.11
7327// cppcheck-suppress funcArgNamesDifferent
7328int sceCdWI(const u8 *buffer, u32 *status)
7329{
7330 int retres;
7331
7332 DelayThread(16000);
7333 *status = SCECdErNO;
7334 retres = set_prev_command(0x13, (const char *)buffer, 8, (char *)status, 1, 1);
7335 DelayThread(16000);
7336 return retres;
7337}
7338
7339// Not implemented XOSD or DVD Player 3.11
7340int sceCdWM(const char *buffer, u32 *status)
7341{
7342 int retres;
7343 char rdata[1];
7344 char wdata[9];
7345
7346 *status = SCECdErNO;
7347 if ( sceCdMV((u8 *)wdata, status) != 1 || (unsigned int)(wdata[3] | (wdata[2] << 8) | (wdata[1] << 16)) < 0x10500 )
7348 {
7349 *status |= 0x40;
7350 return 1;
7351 }
7352 DelayThread(2000);
7353 wdata[0] = 0;
7354 // The following was inlined
7355 memcpy(&wdata[1], &buffer[0], sizeof(wdata) - 1);
7356 retres = set_prev_command(0x18, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7357 *status = rdata[0];
7358 DelayThread(16000);
7359 wdata[0] = 8;
7360 // The following was inlined
7361 memcpy(&wdata[1], &buffer[8], sizeof(wdata) - 1);
7362 retres = set_prev_command(0x18, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && retres;
7363 *status |= rdata[0];
7364 DelayThread(16000);
7365 return !!retres;
7366}
7367
7368// cppcheck-suppress funcArgNamesDifferent
7369int sceCdReadConsoleID(u8 *buffer, u32 *status)
7370{
7371 int retval;
7372 char rdata[9];
7373 char wdata[1];
7374
7375 wdata[0] = 0x45;
7376 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7377 *status = rdata[0];
7378 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7379 return retval;
7380}
7381
7382// Not implemented XOSD or DVD Player 3.11
7383int sceCdWriteConsoleID(const u8 *buffer, u32 *status)
7384{
7385 int retval;
7386 char wdata[9];
7387
7388 DelayThread(16000);
7389 *status = SCECdErNO;
7390 wdata[0] = 0x44;
7391 memcpy(&wdata[1], buffer, 8);
7392 retval = set_prev_command(0x03, wdata, sizeof(wdata), (char *)status, 1, 1);
7393 DelayThread(16000);
7394 return retval;
7395}
7396#endif
7397
7398int sceCdMV(u8 *buffer, u32 *status)
7399{
7400 int retval;
7401 char rdata[4];
7402 char wdata[1];
7403
7404 wdata[0] = 0x00;
7405 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7406#ifdef CDVD_VARIANT_XOSD
7407 *status = SCECdErNO;
7408#else
7409 *status = rdata[0] & 0x80;
7410#endif
7411 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]);
7412#ifndef CDVD_VARIANT_XOSD
7413 rdata[0] &= ~0x80;
7414#endif
7415 memcpy(buffer, rdata, sizeof(rdata));
7416 return retval;
7417}
7418
7419#ifdef CDVD_VARIANT_XOSD
7420static int cdvdman_get_renewal_date(u8 *buffer, u32 *status)
7421{
7422 int retval;
7423 char rdata[6];
7424 char wdata[1];
7425
7426 *status = SCECdErNO;
7427 wdata[0] = 0xFD;
7428 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7429 if ( retval )
7430 {
7431 *status = (u8)rdata[0];
7432 }
7433 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7434 return retval;
7435}
7436#endif
7437
7438#ifndef CDVD_VARIANT_XOSD
7439static int cdvdman_scmd_sender_03_30(u8 *buf, u32 *status)
7440{
7441 int retval;
7442 char rdata[2];
7443 char wdata[2];
7444
7445 if ( g_cdvdman_minver_50000 )
7446 {
7447 return 0;
7448 }
7449 wdata[0] = 0x30;
7450 wdata[1] = 2;
7451 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7452 *status = (u8)rdata[0];
7453 *buf = rdata[1];
7454 return retval;
7455}
7456#endif
7457
7458#ifdef CDVD_VARIANT_OSD
7459int sceCdReadSUBQ(void *buffer, u32 *status)
7460{
7461 int retval;
7462 int i;
7463 int dev5_reg_00E;
7464 int dev5_reg_00D;
7465 int dev5_reg_00C;
7466 char rdata[11];
7467 u32 efbits;
7468 USE_DEV5_MMIO_HWPORT();
7469
7470 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
7471 {
7472 return 0;
7473 }
7474 dev5_mmio_hwport->m_dev5_reg_009 = 0;
7475 retval = cdvdman_send_scmd2(0x02, NULL, 0, rdata, sizeof(rdata), 0);
7476 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7477 for ( i = 0; i < 10; i += 1 )
7478 {
7479 int tmp00E;
7480 int tmp00D;
7481 int tmp00C;
7482
7483 dev5_reg_00E = dev5_mmio_hwport->m_dev5_reg_00E;
7484 dev5_reg_00D = dev5_mmio_hwport->m_dev5_reg_00D;
7485 dev5_reg_00C = dev5_mmio_hwport->m_dev5_reg_00C;
7486 tmp00E = dev5_mmio_hwport->m_dev5_reg_00E;
7487 tmp00D = dev5_mmio_hwport->m_dev5_reg_00D;
7488 tmp00C = dev5_mmio_hwport->m_dev5_reg_00C;
7489 if ( dev5_reg_00E == tmp00E && dev5_reg_00D == tmp00D && dev5_reg_00C == tmp00C )
7490 {
7491 break;
7492 }
7493 }
7494 if ( i != 10 )
7495 {
7496 *((u8 *)buffer + 9) = dev5_reg_00E;
7497 *((u8 *)buffer + 8) = dev5_reg_00D;
7498 *((u8 *)buffer + 7) = dev5_reg_00C;
7499 }
7500 *status = rdata[0];
7501 vSetEventFlag(g_scmd_evfid, 1);
7502 return retval;
7503}
7504
7505// cppcheck-suppress funcArgNamesDifferent
7506int sceCdForbidDVDP(u32 *status)
7507{
7508 int retval;
7509 char rdata[1];
7510
7511 // Unofficial: NULL for wdata if length is 0
7512 retval = set_prev_command(0x15, NULL, 0, rdata, sizeof(rdata), 1);
7513 *status = (u8)rdata[0];
7514 return retval;
7515}
7516#endif
7517
7518int sceCdMmode(int media)
7519{
7520 g_cdvdman_mmode = media;
7521 return 1;
7522}
7523
7524#ifdef CDVD_VARIANT_OSD
7525// cppcheck-suppress funcArgNamesDifferent
7526int sceCdForbidRead(u32 *status)
7527{
7528 *status = SCECdErNO;
7529 // Unofficial: NULL for wdata if length is 0
7530 return set_prev_command(0x19, NULL, 0, (char *)status, 1, 1);
7531}
7532
7533int sceCdBootCertify(const u8 *romname)
7534{
7535 char rdata[1];
7536
7537 VERBOSE_KPRINTF(1, "BC %d %d %d %d\n", *romname, romname[1], romname[2], romname[3]);
7538 return set_prev_command(0x1A, (const char *)romname, 4, rdata, sizeof(rdata), 1);
7539}
7540#endif
7541
7542// cppcheck-suppress funcArgNamesDifferent
7543int sceCdCancelPOffRdy(u32 *status)
7544{
7545 *status = SCECdErNO;
7546 // Unofficial: NULL for wdata if length is 0
7547 return g_cdvdman_minver_20400 ? set_prev_command(0x1B, NULL, 0, (char *)status, 1, 1) : 1;
7548}
7549
7550#ifdef CDVD_VARIANT_OSD
7551// cppcheck-suppress funcArgNamesDifferent
7552int sceCdBlueLEDCtl(u8 control, u32 *status)
7553{
7554 char wdata[1];
7555
7556 *status = SCECdErNO;
7557 wdata[0] = control;
7558 return set_prev_command(0x1C, wdata, sizeof(wdata), (char *)status, 1, 1);
7559}
7560#endif
7561
7562static unsigned int power_off_alarm_cb(void *userdata)
7563{
7565
7566 s = (cdvdman_internal_struct_t *)userdata;
7567 s->m_power_flag = 0;
7568 return 0;
7569}
7570
7571// cppcheck-suppress funcArgNamesDifferent
7572int sceCdPowerOff(u32 *status)
7573{
7574 int retval;
7575
7576 *status = SCECdErNO;
7577 VERBOSE_KPRINTF(1, "sceCdPowerOff Call\n");
7578#ifndef CDVD_VARIANT_XOSD
7579 if ( !g_cdvdman_minver_x_model_15 )
7580 {
7581 while ( (sceCdStatus() & SCECdStatShellOpen) )
7582 {
7583 u32 traychk;
7584
7585 sceCdTrayReq(SCECdTrayClose, &traychk);
7586 vDelayThread(250000);
7587 }
7588 }
7589#endif
7590 retval = set_prev_command(0x0F, NULL, 0, (char *)status, 1, 1);
7591 if ( !retval )
7592 {
7593 g_cdvdman_istruct.m_power_flag = 0;
7594 return 0;
7595 }
7596 KPRINTF("PowerOff Start...\n");
7597 g_cdvdman_istruct.m_power_flag = 1;
7598 g_cdvdman_power_off_timeout.hi = 0;
7599 g_cdvdman_power_off_timeout.lo = 0xAFC8000;
7600 vSetAlarm(&g_cdvdman_power_off_timeout, power_off_alarm_cb, &g_cdvdman_istruct);
7601 return retval;
7602}
7603
7604int sceCdCtrlADout(int mode, u32 *status)
7605{
7606 char wdata[1];
7607
7608 *status = SCECdErNO;
7609 DelayThread(2000);
7610 VERBOSE_KPRINTF(1, "Audio Digital Out: Set param %d\n", (u8)mode);
7611 wdata[0] = mode;
7612 return set_prev_command(0x14, wdata, sizeof(wdata), (char *)status, 1, 1);
7613}
7614
7615#ifdef CDVD_VARIANT_OSD
7616// cppcheck-suppress funcArgNamesDifferent
7617int sceCdAutoAdjustCtrl(int mode, u32 *status)
7618{
7619 char wdata[1];
7620
7621 *status = SCECdErNO;
7622 DelayThread(2000);
7623 VERBOSE_KPRINTF(1, "Auto Adjust Ctrl: Set param %d\n", (u8)mode);
7624 wdata[0] = mode;
7625 return set_prev_command(0x16, wdata, sizeof(wdata), (char *)status, 1, 1);
7626}
7627
7628// TODO clock argument not const
7629int sceCdWriteWakeUpTime(const sceCdCLOCK *clock, u16 userdata, int flags)
7630{
7631 unsigned int clkmonth;
7632 unsigned int clkday;
7633 char wdata[8];
7634
7635 if ( !g_cdvdman_minver_50000 )
7636 {
7637 return 0;
7638 }
7639 clkmonth = 10 * (clock->month >> 4) + (clock->month & 0xF);
7640 clkday = 10 * (clock->day >> 4) + (clock->day & 0xF);
7641 if (
7642 (10 * (clock->second >> 4) + (clock->second & 0xF) >= 0x3C
7643 || 10 * (clock->minute >> 4) + (clock->minute & 0xF) >= 0x3C
7644 || 10 * (clock->hour >> 4) + (clock->hour & 0xF) >= 0x18 || 10 * (clock->year >> 4) + (clock->year & 0xF) >= 0x64
7645 || clkmonth >= 0xD || !clkmonth || clkday >= 0x20 || !clkday)
7646 && flags != 255 && !(clock->second & 0x80) && !(clock->minute & 0x80) )
7647 {
7648 return 0;
7649 }
7650 wdata[0] = (flags == 255) ? 255 : clock->second;
7651 wdata[1] = clock->minute | ((flags == 1) ? 0x80 : 0);
7652 wdata[2] = clock->hour;
7653 wdata[3] = clock->day;
7654 wdata[4] = clock->month;
7655 wdata[5] = clock->year;
7656 wdata[6] = userdata & 0xFF;
7657 wdata[7] = (userdata >> 8) & 0xFF;
7658 return set_prev_command(0x21, wdata, sizeof(wdata), (char *)&clock->stat, sizeof(clock->stat), 1);
7659}
7660
7661int sceCdReadWakeUpTime(sceCdCLOCK *clock, u16 *userdata, u32 *wakeupreason, int *flags)
7662{
7663 int retval;
7664 char rdata[10];
7665
7666 clock->year = 0;
7667 clock->month = 0;
7668 clock->day = 0;
7669 clock->pad = 0;
7670 clock->hour = 0;
7671 clock->minute = 0;
7672 clock->second = 0;
7673 clock->stat = 0;
7674 *userdata = 0;
7675 *wakeupreason = 0;
7676 *flags = 0;
7677 if ( !g_cdvdman_minver_50000 )
7678 {
7679 *wakeupreason = 256;
7680 return 1;
7681 }
7682 retval = set_prev_command(0x22, NULL, 0, rdata, sizeof(rdata), 1);
7683 if ( !retval )
7684 {
7685 return 0;
7686 }
7687 clock->stat = rdata[0];
7688 clock->second = (u8)rdata[2] == 255 ? -1 : (rdata[2] & 0x7F);
7689 clock->minute = rdata[3] & 0x7F;
7690 clock->pad = 0;
7691 clock->hour = rdata[4];
7692 clock->day = rdata[5];
7693 clock->month = rdata[6];
7694 clock->year = rdata[7];
7695 *userdata = (u8)rdata[8] | ((u8)rdata[9] << 8);
7696 *wakeupreason = (u8)rdata[1];
7697 *flags = (((u8)rdata[2] >> 7) << 1) | (!!(rdata[3] & 0x80));
7698 return retval;
7699}
7700
7701int sceCdSendSCmd1D(int *arg1, unsigned int *arg2, unsigned int *arg3, u32 *status)
7702{
7703 int retval;
7704 char rdata[5];
7705 u32 rdata2tmp;
7706
7707 *arg3 = 0;
7708 *arg2 = 0;
7709 *arg1 = 0;
7710 if ( !g_cdvdman_minver_50000 )
7711 {
7712 *status = 256;
7713 return 1;
7714 }
7715 *status = SCECdErNO;
7716 retval = set_prev_command(0x1D, NULL, 0, rdata, sizeof(rdata), 1);
7717 if ( retval != 1 )
7718 {
7719 return retval;
7720 }
7721 *status = (u8)rdata[0];
7722 *arg1 = (u8)rdata[1];
7723 rdata2tmp = rdata[4] | (rdata[3] << 8) | (rdata[2] << 16);
7724 switch ( *arg1 )
7725 {
7726 case 12:
7727 *arg2 = (rdata2tmp >> 17) & 0x7F;
7728 *arg3 = (rdata2tmp >> 12) & 0x1F;
7729 return 1;
7730 case 15:
7731 *arg2 = (rdata2tmp >> 17) & 0x7F;
7732 *arg3 = (rdata2tmp >> 9) & 0xFF;
7733 return 1;
7734 case 20:
7735 *arg2 = (rdata2tmp >> 17) & 0x7F;
7736 *arg3 = (rdata2tmp >> 4) & 0x1FFF;
7737 return 1;
7738 default:
7739 return 0;
7740 }
7741}
7742
7743int sceRemote2_7(u16 param, u32 *status)
7744{
7745 char wdata[2];
7746
7747 if ( !g_cdvdman_minver_50000 )
7748 {
7749 *status = 256;
7750 return 1;
7751 }
7752 *status = SCECdErNO;
7753 wdata[0] = param & 0xFF;
7754 wdata[1] = (param >> 8) & 0xFF;
7755 return set_prev_command(0x1F, wdata, sizeof(wdata), (char *)status, 1, 1);
7756}
7757
7758int sceRemote2_7Get(u32 *param, u32 *status)
7759{
7760 int retval;
7761 char rdata[3];
7762
7763 *param = 0;
7764 if ( !g_cdvdman_minver_50000 )
7765 {
7766 *status = 256;
7767 return 1;
7768 }
7769 *status = SCECdErNO;
7770 retval = set_prev_command(0x26, NULL, 0, rdata, sizeof(rdata), 1);
7771 *param = ((u8)rdata[2] << 8) | (u8)rdata[1];
7772 *status = (u8)rdata[0];
7773 return retval;
7774}
7775
7776// cppcheck-suppress funcArgNamesDifferent
7777int sceCdReadPS1BootParam(u8 *out, u32 *status)
7778{
7779 int retval;
7780 char rdata[13];
7781
7782 memset(out, 0, 11);
7783 if ( !g_cdvdman_minver_50200 )
7784 {
7785 *status = 256;
7786 return 1;
7787 }
7788 *status = SCECdErNO;
7789 retval = set_prev_command(0x27, NULL, 0, (char *)rdata, sizeof(rdata), 1);
7790 memcpy(out, &rdata[1], sizeof(rdata) - 2);
7791 *status = rdata[0];
7792 return retval;
7793}
7794
7795// cppcheck-suppress funcArgNamesDifferent
7796int sceCdSetFanProfile(u8 param, u32 *status)
7797{
7798 int retval;
7799 char rdata[1];
7800 char wdata[1];
7801
7802 if ( !g_cdvdman_minver_50400 )
7803 {
7804 *status = 256;
7805 return 1;
7806 }
7807 *status = SCECdErNO;
7808 wdata[0] = param;
7809 retval = set_prev_command(0x28, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7810 *status = (u8)rdata[0];
7811 return retval;
7812}
7813
7814int cdvdman_152(u32 *param, u32 *status)
7815{
7816 int retval;
7817 char rdata[3];
7818 char wdata[1];
7819
7820 if ( !g_cdvdman_minver_50400 )
7821 {
7822 *status = 256;
7823 *param = 0;
7824 return 1;
7825 }
7826 *status = SCECdErNO;
7827 wdata[0] = 0xEF;
7828 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7829 *param = 3125 * (((u8)rdata[2] | ((u8)rdata[1] << 8)) << 16 >> 18) / 100;
7830 *status = (u8)rdata[0];
7831 return retval;
7832}
7833#endif
7834
7835#ifdef CDVD_VARIANT_XOSD
7836// cppcheck-suppress funcArgNamesDifferent
7837int sceCdNoticeGameStart(u8 arg1, u32 *status)
7838{
7839 int retval;
7840 char rdata[1];
7841 char wdata[1];
7842
7843 if ( !g_cdvdman_minver_50400 )
7844 {
7845 *status = 256;
7846 return 1;
7847 }
7848 *status = SCECdErNO;
7849 wdata[0] = arg1;
7850 retval = set_prev_command(0x29, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7851 *status = (u8)rdata[0];
7852 if ( retval && !rdata[0] )
7853 {
7854 g_cdvdman_istruct.m_medium_removal_state = 0;
7855 }
7856 return retval;
7857}
7858#endif
7859
7860#ifdef CDVD_VARIANT_OSD
7861int sceCdRcBypassCtl(int mode, u32 *status)
7862{
7863 char wdata[1];
7864 USE_IOP_MMIO_HWPORT();
7865
7866 if ( mfc0(PRID) >= 0x23 )
7867 {
7868 if ( mode & 0xFF )
7869 {
7870 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] |= 1;
7871 }
7872 else
7873 {
7874 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] &= ~1;
7875 }
7876 *status = SCECdErNO;
7877 return 1;
7878 }
7879 if ( !g_cdvdman_minver_50000 )
7880 {
7881 *status = 256;
7882 return 1;
7883 }
7884 *status = SCECdErNO;
7885 wdata[0] = mode;
7886 return set_prev_command(0x24, wdata, sizeof(wdata), (char *)status, 1, 1);
7887}
7888
7889// cppcheck-suppress funcArgNamesDifferent
7890int sceCdReadRegionParams(u32 *param, u32 *status)
7891{
7892 int retval;
7893 char rdata[15];
7894
7895 memset(param, 0, 15);
7896 if ( !g_cdvdman_minver_60000 )
7897 {
7898 *status = 256;
7899 return 1;
7900 }
7901 *status = SCECdErNO;
7902 retval = set_prev_command(0x36, NULL, 0, rdata, sizeof(rdata), 1);
7903 memcpy(param, &rdata[1], sizeof(rdata) - 1);
7904 *status = rdata[0];
7905 return retval;
7906}
7907
7908// Not implemented XOSD or DVD Player 3.11
7909// TODO const arg2 arg3
7910// cppcheck-suppress funcArgNamesDifferent
7911int sceCdWriteRegionParams(u8 arg1, u32 *arg2, u8 *arg3, u32 *status)
7912{
7913 char wdata[15];
7914
7915 *status = SCECdErNO;
7916 memset(wdata, 0, sizeof(wdata));
7917 if ( !g_cdvdman_minver_60600 )
7918 {
7919 *status = 256;
7920 return 1;
7921 }
7922 wdata[0] = arg1;
7923 // The following was inlined
7924 memcpy(&wdata[1], arg2, 12);
7925 // The following was inlined
7926 memcpy(&wdata[13], arg3, 2);
7927 return set_prev_command(0x3E, wdata, sizeof(wdata), (char *)status, 1, 1);
7928}
7929
7930// cppcheck-suppress funcArgNamesDifferent
7931int sceCdSetLEDsMode(u32 param, u32 *status)
7932{
7933 char wdata[1];
7934
7935 if ( !g_cdvdman_minver_50000 )
7936 {
7937 *status = 256;
7938 return 1;
7939 }
7940 *status = SCECdErNO;
7941 wdata[0] = param;
7942 return set_prev_command(0x25, wdata, sizeof(wdata), (char *)status, 1, 1);
7943}
7944#endif
7945
7947{
7948 int retval;
7949
7950 retval = set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7951 clock->pad = 0;
7952 clock->month &= 0x7F;
7953 if ( retval && !clock->stat )
7954 {
7955 memcpy(&g_cdvdman_clock, clock, sizeof(g_cdvdman_clock));
7956 g_cdvdman_clk_flg = 1;
7957 }
7958 else if ( g_cdvdman_clk_flg )
7959 {
7960 memcpy(clock, &g_cdvdman_clock, sizeof(g_cdvdman_clock));
7961 }
7962 else
7963 {
7964 clock->month = 3;
7965 clock->day = 4;
7966 clock->hour = 5;
7967 clock->minute = 6;
7968 clock->year = 0;
7969 clock->second = 7;
7970 }
7971 return retval;
7972}
7973
7974int sceCdRC(sceCdCLOCK *clock)
7975{
7976 return set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7977}
7978
7979#ifdef CDVD_VARIANT_OSD
7980int sceCdWriteClock(sceCdCLOCK *clock)
7981{
7982 return set_prev_command(
7983 0x09, (const char *)&clock->second, sizeof(clock) - 1, (char *)&clock->stat, sizeof(clock->second), 1);
7984}
7985
7986int sceCdReadNVM(u32 address, u16 *data, u8 *result)
7987{
7988 int retval;
7989 char rdata[3];
7990 char wdata[2];
7991
7992 wdata[0] = (address >> 8) & 0xFF;
7993 wdata[1] = address & 0xFF;
7994 retval = set_prev_command(0x0A, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7995 *result = rdata[0];
7996 *data = (rdata[1] << 8) | rdata[2];
7997 VERBOSE_KPRINTF(1, "RN_call addr= 0x%04x data= 0x%04x stat= 0x%02x\n", address, *data, *result);
7998 return retval;
7999}
8000
8001int sceCdWriteNVM(u32 address, u16 data, u8 *result)
8002{
8003 int retval;
8004 char wdata[4];
8005
8006 wdata[0] = (address >> 8) & 0xFF;
8007 wdata[1] = address & 0xFF;
8008 wdata[2] = (data >> 8) & 0xFF;
8009 wdata[3] = data & 0xFF;
8010 retval = set_prev_command(0x0B, wdata, sizeof(wdata), (char *)result, 1, 1);
8011 VERBOSE_KPRINTF(1, "WN_call addr= 0x%04x data= 0x%04x stat= 0x%02x\n", address, data, *result);
8012 return retval;
8013}
8014#endif
8015
8016int sceCdTrayReq(int param, u32 *traychk)
8017{
8018 char wdata[1];
8019 char rdata[1];
8020#ifdef CDVD_VARIANT_XOSD
8021 int state;
8022#endif
8023
8024 if ( param == SCECdTrayCheck )
8025 {
8026 *traychk = cdvdman_mediactl(1);
8027 VERBOSE_KPRINTF(1, "Tray Req test = %d\n", *traychk);
8028 return 1;
8029 }
8030 if ( g_cdvdman_minver_x_model_15 && param == SCECdTrayClose )
8031 {
8032 return 1;
8033 }
8034 wdata[0] = param;
8035 g_cdvdman_iocache = 0;
8036#ifdef CDVD_VARIANT_XOSD
8037 CpuSuspendIntr(&state);
8038#endif
8039 rdata[0] = !!set_prev_command(0x06, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0];
8040#ifdef CDVD_VARIANT_XOSD
8041 CpuResumeIntr(state);
8042#endif
8043 if ( rdata[0] )
8044 {
8045#ifdef CDVD_VARIANT_XOSD
8046 if ( !param )
8047 {
8048 g_cdvdman_istruct.m_medium_removal_state = 0;
8049 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
8050 }
8051#endif
8052 vDelayThread(11000);
8053 }
8054 return rdata[0];
8055}
8056
8057static int cdvdman_scmd_sender_3B(int arg1)
8058{
8059 char wdata[1];
8060 char rdata[1];
8061
8062 if ( g_cdvdman_minver_x_model_15 && arg1 == 1 )
8063 {
8064 return 1;
8065 }
8066 g_cdvdman_iocache = 0;
8067 wdata[0] = arg1;
8068 if ( set_prev_command(0x3B, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0] )
8069 {
8070 vDelayThread(11000);
8071 return 1;
8072 }
8073 return 0;
8074}
8075
8076#ifdef CDVD_VARIANT_DNAS
8077int sceCdReadDiskID(unsigned int *id)
8078{
8079 sceCdRMode rmode;
8080 char sectbuf[0x800];
8081 u32 efbits;
8082 USE_DEV5_MMIO_HWPORT();
8083
8084 // The following was inlined
8085 memset(id, 0, 5);
8086#ifdef CDVD_VARIANT_XOSD
8087 switch ( get_disk_type_ex() )
8088#else
8089 switch ( sceCdGetDiskType() )
8090#endif
8091 {
8092 case SCECdPS2CD:
8093 case SCECdPS2CDDA:
8094 case SCECdPS2DVD:
8095 break;
8096 default:
8097 return 0;
8098 }
8099 rmode.spindlctrl = 0x12;
8100 rmode.datapattern = SCECdSecS2048;
8101 rmode.trycount = 0;
8102 sceCdRead0(0x4B, 1, sectbuf, &rmode, 0, 0);
8103 sceCdSync(3);
8104 if ( !cdvdman_ncmd_sender_0C(0, 0, 0x4B) )
8105 {
8106 return 0;
8107 }
8108 sceCdSync(3);
8109 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8110 {
8111 return 0;
8112 }
8113 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8114 if ( !(dev5_mmio_hwport->m_dev5_reg_038 & 4) )
8115 {
8116 vSetEventFlag(g_scmd_evfid, 1);
8117 return 0;
8118 }
8119 *(u8 *)id = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
8120 *((u8 *)id + 1) = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
8121 *((u8 *)id + 2) = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
8122 *((u8 *)id + 3) = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
8123 *((u8 *)id + 4) = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
8124 vSetEventFlag(g_scmd_evfid, 1);
8125 return 1;
8126}
8127
8128int sceCdDoesUniqueKeyExist(u32 *status)
8129{
8130 int is_cd;
8131 u8 dev5_reg_038;
8132 sceCdRMode rmode;
8133 char ndata[7];
8134 int state;
8135 u32 efbits;
8136 USE_DEV5_MMIO_HWPORT();
8137
8138 if ( !g_cdvdman_istruct.m_cd_inited )
8139 {
8140 *status = SCECdErCUD;
8141 return 0;
8142 }
8143 *status = SCECdErNO;
8144#ifdef CDVD_VARIANT_XOSD
8145 switch ( get_disk_type_ex() )
8146#else
8147 switch ( sceCdGetDiskType() )
8148#endif
8149 {
8150 case SCECdPS2CD:
8151 case SCECdPS2CDDA:
8152 is_cd = 1;
8153 break;
8154 case SCECdPS2DVD:
8155 is_cd = 0;
8156 break;
8157 default:
8158 *status = SCECdErCUD;
8159 return 0;
8160 }
8161 CpuSuspendIntr(&state);
8162 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8163 {
8164 *status = SCECdErREADCF;
8165 CpuResumeIntr(state);
8166 return 0;
8167 }
8168 if ( (sceCdStatus() & SCECdStatSpin) )
8169 {
8170 CpuResumeIntr(state);
8171 }
8172 else
8173 {
8174 dev5_mmio_hwport->m_dev5_reg_007 = 1;
8175 CpuResumeIntr(state);
8176 sceCdSync(3);
8177 }
8178 CpuSuspendIntr(&state);
8179 rmode.spindlctrl = 0x12;
8180 rmode.datapattern = SCECdSecS2048;
8181 rmode.trycount = 0;
8182 if ( is_cd )
8183 {
8184 unsigned int i;
8185
8186 for ( i = 0; i < 20; i += 1 )
8187 {
8188 sceCdRead0(0x4B + (0x10 * i), 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
8189 CpuResumeIntr(state);
8190 sceCdSync(3);
8191 CpuSuspendIntr(&state);
8192 }
8193 CpuResumeIntr(state);
8194 }
8195 else
8196 {
8197 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
8198 CpuResumeIntr(state);
8199 sceCdSync(3);
8200 }
8201 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8202 CpuSuspendIntr(&state);
8203 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8204 {
8205 *status = SCECdErREADCF;
8206 CpuResumeIntr(state);
8207 vSetEventFlag(g_scmd_evfid, 1);
8208 return 0;
8209 }
8210 // The following was inlined
8211 memset(ndata, 0, sizeof(ndata));
8212 ndata[3] = 0x4B;
8213 if ( cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) < 0 )
8214 {
8215 *status = SCECdErREADCF;
8216 CpuResumeIntr(state);
8217 vSetEventFlag(g_scmd_evfid, 1);
8218 return 0;
8219 }
8220 CpuResumeIntr(state);
8221 sceCdSync(3);
8222 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8223 {
8224 *status = (u8)g_cdvdman_istruct.m_last_error;
8225 vSetEventFlag(g_scmd_evfid, 1);
8226 return 0;
8227 }
8228 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
8229 vSetEventFlag(g_scmd_evfid, 1);
8230 return (dev5_reg_038 & 5) == 5;
8231}
8232#endif
8233
8234#ifdef CDVD_VARIANT_XOSD
8235int sceCdDeobfuscateUsingUniqueKey(u8 *buffer, unsigned int shiftval, int xorval, u32 *status)
8236{
8237 int is_cd;
8238 int retval;
8239 int i;
8240 u8 xor_val_1_stk;
8241 u8 xor_val_2_stk;
8242 u8 xor_val_3_stk;
8243 u8 xor_val_4_stk;
8244 u8 xor_val_1_xstk;
8245 u8 xor_val_2_xstk;
8246 char xorarea[16];
8247 char ndata[7];
8248 sceCdRMode rmode;
8249 int state;
8250 u32 efbits;
8251 USE_DEV5_MMIO_HWPORT();
8252
8253 memset(xorarea, 0, sizeof(xorarea));
8254 memset(buffer, 0, 16);
8255 *status = SCECdErNO;
8256 if ( shiftval >= 8 || xorval < 0 || xorval >= 256 )
8257 {
8258 *status = SCECdErREADCF;
8259 return 0;
8260 }
8261 if ( !g_cdvdman_istruct.m_cd_inited )
8262 {
8263 *status = SCECdErCUD;
8264 return 0;
8265 }
8266 switch ( get_disk_type_ex() )
8267 {
8268 case SCECdPS2CD:
8269 case SCECdPS2CDDA:
8270 is_cd = 1;
8271 break;
8272 case SCECdPS2DVD:
8273 is_cd = 0;
8274 break;
8275 default:
8276 *status = SCECdErCUD;
8277 return 0;
8278 }
8279 CpuSuspendIntr(&state);
8280 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8281 {
8282 *status = SCECdErREADCF;
8283 CpuResumeIntr(state);
8284 return 0;
8285 }
8286 if ( !(sceCdStatus() & SCECdStatSpin) )
8287 {
8288 dev5_mmio_hwport->m_dev5_reg_007 = 1;
8289 CpuResumeIntr(state);
8290 sceCdSync(3);
8291 CpuSuspendIntr(&state);
8292 }
8293 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8294 {
8295 *status = SCECdErREADCF;
8296 CpuResumeIntr(state);
8297 return 0;
8298 }
8299 rmode.spindlctrl = 0x12;
8300 rmode.datapattern = SCECdSecS2048;
8301 rmode.trycount = 0;
8302 if ( is_cd )
8303 {
8304 for ( i = 0; i < 0x14; i += 1 )
8305 {
8306 sceCdRead0(75 + 16 * i, 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
8307 CpuResumeIntr(state);
8308 sceCdSync(3);
8309 CpuSuspendIntr(&state);
8310 }
8311 CpuResumeIntr(state);
8312 }
8313 else
8314 {
8315 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
8316 CpuResumeIntr(state);
8317 sceCdSync(3);
8318 }
8319 WaitEventFlag(g_scmd_evfid, 1, 0, &efbits);
8320 CpuSuspendIntr(&state);
8321 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8322 {
8323 *status = SCECdErREADCF;
8324 CpuResumeIntr(state);
8325 vSetEventFlag(g_scmd_evfid, 1);
8326 return 0;
8327 }
8328 // The following was inlined
8329 memset(ndata, 0, sizeof(ndata));
8330 ndata[3] = 0x4B;
8331 if ( cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) < 0 )
8332 {
8333 *status = SCECdErREADCF;
8334 CpuResumeIntr(state);
8335 vSetEventFlag(g_scmd_evfid, 1);
8336 return 0;
8337 }
8338 CpuResumeIntr(state);
8339 sceCdSync(3);
8340 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8341 {
8342 *status = (u8)g_cdvdman_istruct.m_last_error;
8343 vSetEventFlag(g_scmd_evfid, 1);
8344 return 0;
8345 }
8346 retval = 0;
8347 xor_val_2_xstk = 0;
8348 xor_val_1_xstk = 0;
8349 xor_val_4_stk = 0;
8350 xor_val_3_stk = 0;
8351 xor_val_2_stk = 0;
8352 xor_val_1_stk = 0;
8353 if ( (dev5_mmio_hwport->m_dev5_reg_038 & 5) == 5 )
8354 {
8355 u8 dev5_reg_020;
8356 u8 dev5_reg_039;
8357 u8 dev5_reg_022;
8358 u8 reg_039_tmp1;
8359
8360 dev5_reg_020 = dev5_mmio_hwport->m_dev5_reg_020;
8361 dev5_reg_039 = dev5_mmio_hwport->m_dev5_reg_039;
8362 xor_val_1_stk = dev5_reg_020 ^ dev5_reg_039;
8363 xor_val_2_stk = dev5_reg_039 ^ dev5_mmio_hwport->m_dev5_reg_021;
8364 dev5_reg_022 = dev5_mmio_hwport->m_dev5_reg_022;
8365 reg_039_tmp1 = dev5_mmio_hwport->m_dev5_reg_039;
8366 xor_val_3_stk = dev5_reg_022 ^ reg_039_tmp1;
8367 xor_val_4_stk = reg_039_tmp1 ^ dev5_mmio_hwport->m_dev5_reg_023;
8368 xor_val_1_xstk = dev5_mmio_hwport->m_dev5_reg_024 ^ dev5_mmio_hwport->m_dev5_reg_039;
8369 xor_val_2_xstk = dev5_mmio_hwport->m_dev5_reg_039 ^ dev5_mmio_hwport->m_dev5_reg_034;
8370 retval = 1;
8371 }
8372 vSetEventFlag(g_scmd_evfid, 1);
8373 xorarea[0] = (xor_val_4_stk >> 4) | ((xor_val_1_xstk << 4) & 0x70);
8374 xorarea[1] = (xor_val_3_stk >> 5) | ((xor_val_4_stk << 3) & 0x78);
8375 xorarea[2] = (xor_val_2_stk >> 6) | ((xor_val_3_stk << 2) & 0x7C);
8376 xorarea[3] = (xor_val_1_stk >> 7) | ((xor_val_2_stk << 1) & 0x7E);
8377 sprintf(&xorarea[4], "%d", ((xor_val_1_stk & 0x7F) << 10) | (xor_val_1_xstk >> 3) | ((xor_val_2_xstk >> 3) << 5));
8378 for ( i = 0; i < 9; i += 1 )
8379 {
8380 xorarea[i] = xorarea[i] ^ xorval;
8381 }
8382 if ( shiftval )
8383 {
8384 for ( i = 0; i < 9; i += 1 )
8385 {
8386 buffer[i] = (xorarea[i] << shiftval) | ((int)(u8)xorarea[i ? i - 1 : 8] >> (8 - shiftval));
8387 }
8388 }
8389 else
8390 {
8391 // The following was inlined
8392 memcpy(buffer, xorarea, sizeof(xorarea));
8393 }
8394 return retval;
8395}
8396#endif
8397
8398#ifdef CDVD_VARIANT_OSD
8399int sceCdReadKey(u8 arg1, u8 arg2, unsigned int command, u8 *key)
8400{
8401 int i;
8402 u8 dev5_reg_038;
8403 sceCdRMode rmode;
8404 char sectorbuf[0x800];
8405 u32 efbits;
8406 USE_DEV5_MMIO_HWPORT();
8407
8408 if ( cdvdman_isdvd() && !arg1 )
8409 {
8410 if ( !DvdDual_infochk() )
8411 {
8412 return 0;
8413 }
8414 command = sceCdLsnDualChg(command);
8415 }
8416 rmode.spindlctrl = 0x12;
8417 rmode.datapattern = SCECdSecS2048;
8418 rmode.trycount = 0;
8419 sceCdRead0(command, 1, sectorbuf, &rmode, 0, 0);
8420 sceCdSync(3);
8421 for ( i = 0; i < 300; i += 1 )
8422 {
8423 if ( !cdvdman_ncmd_sender_0C(arg1, arg2, command + i) )
8424 {
8425 return 0;
8426 }
8427 sceCdSync(3);
8428 if ( g_cdvdman_istruct.m_last_error == SCECdErNO )
8429 {
8430 break;
8431 }
8432 }
8433 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8434 // The following was inlined
8435 memset(key, 0, 16);
8436 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
8437 if ( (dev5_reg_038 & 1) )
8438 {
8439 key[0] = dev5_mmio_hwport->m_dev5_reg_020 ^ dev5_mmio_hwport->m_dev5_reg_039;
8440 key[1] = dev5_mmio_hwport->m_dev5_reg_021 ^ dev5_mmio_hwport->m_dev5_reg_039;
8441 key[2] = dev5_mmio_hwport->m_dev5_reg_022 ^ dev5_mmio_hwport->m_dev5_reg_039;
8442 key[3] = dev5_mmio_hwport->m_dev5_reg_023 ^ dev5_mmio_hwport->m_dev5_reg_039;
8443 key[4] = dev5_mmio_hwport->m_dev5_reg_024 ^ dev5_mmio_hwport->m_dev5_reg_039;
8444 }
8445 if ( (dev5_reg_038 & 2) )
8446 {
8447 key[5] = dev5_mmio_hwport->m_dev5_reg_028 ^ dev5_mmio_hwport->m_dev5_reg_039;
8448 key[6] = dev5_mmio_hwport->m_dev5_reg_029 ^ dev5_mmio_hwport->m_dev5_reg_039;
8449 key[7] = dev5_mmio_hwport->m_dev5_reg_02A ^ dev5_mmio_hwport->m_dev5_reg_039;
8450 key[8] = dev5_mmio_hwport->m_dev5_reg_02B ^ dev5_mmio_hwport->m_dev5_reg_039;
8451 key[9] = dev5_mmio_hwport->m_dev5_reg_02C ^ dev5_mmio_hwport->m_dev5_reg_039;
8452 }
8453 if ( (dev5_reg_038 & 4) )
8454 {
8455 key[10] = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
8456 key[11] = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
8457 key[12] = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
8458 key[13] = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
8459 key[14] = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
8460 }
8461 key[15] = dev5_reg_038 & 7;
8462 vSetEventFlag(g_scmd_evfid, 1);
8463 return 1;
8464}
8465#endif
8466
8467#ifdef CDVD_VARIANT_DNAS
8468static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3)
8469{
8470 char ndata[7];
8471
8472 ndata[1] = !!arg2;
8473 ndata[0] = arg1;
8474 ndata[2] = !!(arg2 >> 8);
8475 *(u32 *)&ndata[3] = !arg1 ? arg3 : 0;
8476 return cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) >= 0;
8477}
8478#endif
8479
8480int sceCdDecSet(u8 enable_xor, u8 enable_shift, u8 shiftval)
8481{
8482#ifdef CDVD_VARIANT_DNAS
8483 USE_DEV5_MMIO_HWPORT();
8484
8485 g_cdvdman_cd36key = enable_shift | shiftval;
8486 dev5_mmio_hwport->m_dev5_reg_03A = ((shiftval & 7) << 4) | ((!!enable_xor) << 1) | (!!enable_shift);
8487#else
8488 (void)enable_xor;
8489 (void)enable_shift;
8490 (void)shiftval;
8491#endif
8492 return 1;
8493}
8494
8495#ifdef CDVD_VARIANT_OSD
8496int sceCdOpenConfig(int block, int mode, int NumBlocks, u32 *status)
8497{
8498 int retval;
8499#ifdef CDVD_VARIANT_XOSD
8500 u32 efbits;
8501#endif
8502 char wdata[3];
8503
8504#ifdef CDVD_VARIANT_XOSD
8505 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8506 {
8507 return 0;
8508 }
8509#endif
8510 DelayThread(16000);
8511 *status = SCECdErNO;
8512 wdata[0] = (u8)mode;
8513 wdata[1] = (u8)block;
8514 wdata[2] = (u8)NumBlocks;
8515 retval = set_prev_command(0x40, wdata, sizeof(wdata), (char *)status, 1, 0);
8516#ifdef CDVD_VARIANT_XOSD
8517 if ( retval == 1 )
8518#endif
8519 {
8520 g_cdvdman_config_numblocks = NumBlocks;
8521 }
8522#ifdef CDVD_VARIANT_XOSD
8523 vSetEventFlag(g_scmd_evfid, 1);
8524#endif
8525 return retval;
8526}
8527
8528// cppcheck-suppress funcArgNamesDifferent
8529int sceCdCloseConfig(u32 *status)
8530{
8531 int retval;
8532
8533 *status = SCECdErNO;
8534 DelayThread(16000);
8535 retval = set_prev_command(0x43, NULL, 0, (char *)status, 1, 1);
8536 g_cdvdman_config_numblocks = 0;
8537 return retval;
8538}
8539
8540static int read_config_process(char *outval, u32 *status)
8541{
8542 int retval;
8543 char rdata[16];
8544
8545 DelayThread(2000);
8546 retval = set_prev_command(0x41, NULL, 0, rdata, sizeof(rdata), 0);
8547 *status = (u8)(rdata[14] + rdata[13] + rdata[12] + rdata[11] + rdata[10] + rdata[9] + rdata[8] + rdata[7] + rdata[6]
8548 + rdata[5] + rdata[4] + rdata[3] + rdata[2] + rdata[0] + rdata[1])
8549 != (u8)rdata[15];
8550 memcpy(outval, rdata, sizeof(rdata) - 1);
8551 return retval;
8552}
8553
8554// cppcheck-suppress funcArgNamesDifferent
8555int sceCdReadConfig(void *buffer, u32 *status)
8556{
8557 int retval;
8558 u32 efbits;
8559
8560 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8561 {
8562 return 0;
8563 }
8564 for ( retval = 0; retval < g_cdvdman_config_numblocks; retval += 1 )
8565 {
8566 if ( !read_config_process((char *)buffer + 15 * retval, status) )
8567 {
8568 VERBOSE_KPRINTF(1, "RC_fail Command busy\n");
8569 break;
8570 }
8571 if ( *status )
8572 {
8573 VERBOSE_KPRINTF(1, "RC_fail status: 0x%02x\n", *status);
8574 break;
8575 }
8576 }
8577 vSetEventFlag(g_scmd_evfid, 1);
8578 return retval;
8579}
8580
8581static int write_config_process(const char *inval, u32 *status)
8582{
8583 char wdata[16];
8584
8585 DelayThread(2000);
8586 *status = SCECdErNO;
8587 memcpy(wdata, inval, 15);
8588 wdata[15] = wdata[14] + wdata[13] + wdata[12] + wdata[11] + wdata[10] + wdata[9] + wdata[8] + wdata[7] + wdata[6]
8589 + wdata[5] + wdata[4] + wdata[3] + wdata[2] + wdata[0] + wdata[1];
8590 return set_prev_command(0x42, wdata, sizeof(wdata), (char *)status, 1, 0);
8591}
8592
8593// cppcheck-suppress funcArgNamesDifferent
8594int sceCdWriteConfig(const void *buffer, u32 *status)
8595{
8596 int retval;
8597 u32 efbits;
8598
8599 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8600 {
8601 return 0;
8602 }
8603 for ( retval = 0; retval < g_cdvdman_config_numblocks; retval += 1 )
8604 {
8605 if ( !write_config_process((char *)buffer + 15 * retval, status) )
8606 {
8607 VERBOSE_KPRINTF(1, "WC_fail Command busy\n");
8608 break;
8609 }
8610 if ( *status )
8611 {
8612 VERBOSE_KPRINTF(1, "WC_fail status: 0x%02x\n", *status);
8613 break;
8614 }
8615 }
8616 vSetEventFlag(g_scmd_evfid, 1);
8617 return retval;
8618}
8619
8620int sceCdSetHDMode(u32 mode)
8621{
8622 char wdata[1];
8623 char rdata[1];
8624
8625 wdata[0] = mode;
8626 return set_prev_command(0x0C, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0];
8627}
8628#endif
8629
8630#ifdef CDVD_VARIANT_XOSD
8631// cppcheck-suppress funcArgNamesDifferent
8632int sceCdXLEDCtl(u8 arg1, u8 arg2, u32 *param, u32 *status)
8633{
8634 int retval;
8635 char wdata[2];
8636 char rdata[2];
8637
8638 *param = 0;
8639 if ( !g_cdvdman_minver_50600 )
8640 {
8641 *status = 256;
8642 return 1;
8643 }
8644 *status = SCECdErNO;
8645 wdata[0] = arg1;
8646 wdata[1] = arg2;
8647 retval = set_prev_command(0x2D, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
8648 if ( !retval )
8649 {
8650 return 0;
8651 }
8652 *status = (u8)rdata[0];
8653 *param = (u8)rdata[1];
8654 return retval;
8655}
8656#endif
8657
8658#ifdef CDVD_VARIANT_XOSD
8659// cppcheck-suppress funcArgNamesDifferent
8660int sceCdBuzzerCtl(u32 *status)
8661{
8662 if ( !g_cdvdman_minver_50600 )
8663 {
8664 *status = 256;
8665 return 1;
8666 }
8667 *status = SCECdErNO;
8668 return set_prev_command(0x2E, NULL, 0, (char *)status, 1, 1);
8669}
8670#endif
8671
8672#ifdef CDVD_VARIANT_XOSD
8673int sceCdResetWakeupReason(u32 *inbuf, u32 *status)
8674{
8675 if ( !g_cdvdman_minver_50600 )
8676 {
8677 *status = 256;
8678 return 1;
8679 }
8680 *status = SCECdErNO;
8681 return cdvdman_write_scmd_swap_dev5(0x2F, (char *)inbuf, 16, (char *)status, 1, 1);
8682}
8683#endif
8684
8685#ifdef CDVD_VARIANT_XOSD
8686int cdvdman_169(u32 *arg1, u32 *status)
8687{
8688 int i;
8689 int retval;
8690 char rdata[9];
8691 u32 efbits;
8692 char wdata[1];
8693
8694 if ( !g_cdvdman_minver_50600 )
8695 {
8696 *status = 256;
8697 return 1;
8698 }
8699 *status = SCECdErNO;
8700 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8701 {
8702 return 0;
8703 }
8704 memset(arg1, 0, 16);
8705 if ( *status )
8706 {
8707 vSetEventFlag(g_scmd_evfid, 1);
8708 return 1;
8709 }
8710 retval = 0;
8711 for ( i = 0; i < 2 && !rdata[0]; i += 1 )
8712 {
8713 wdata[0] = i * 8;
8714 retval = 0;
8715 while ( !retval )
8716 {
8717 DelayThread(2000);
8718 retval = cdvdman_write_scmd_swap_dev5(0x30, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
8719 memcpy(&arg1[i * 2], &rdata[1], sizeof(rdata) - 1);
8720 *status = rdata[0];
8721 }
8722 }
8723 return retval;
8724}
8725#endif
8726
8727#ifdef CDVD_VARIANT_XOSD
8728// cppcheck-suppress funcArgNamesDifferent
8729int sceCdXBSPowerCtl(u8 arg1, u8 arg2, u32 *param, u32 *status)
8730{
8731 int retval;
8732 char wdata[2];
8733 char rdata[2];
8734
8735 *param = 0;
8736 if ( !g_cdvdman_minver_50600 )
8737 {
8738 *status = 256;
8739 return 1;
8740 }
8741 *status = SCECdErNO;
8742 wdata[0] = arg1;
8743 wdata[1] = arg2;
8744 retval = set_prev_command(0x2C, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
8745 if ( !retval )
8746 {
8747 return 0;
8748 }
8749 *status = (u8)rdata[0];
8750 *param = (u8)rdata[1];
8751 return retval;
8752}
8753#endif
8754
8755#ifdef CDVD_VARIANT_XOSD
8756// cppcheck-suppress funcArgNamesDifferent
8757int sceCdSetMediumRemoval(u8 wanted_val, u32 *status)
8758{
8759 int retval;
8760 int saved_medium_removal_state;
8761 char wdata[1];
8762 int state;
8763
8764 if ( !g_cdvdman_minver_50600 )
8765 {
8766 *status = 256;
8767 return 1;
8768 }
8769 *status = SCECdErNO;
8770 CpuSuspendIntr(&state);
8771 saved_medium_removal_state = g_cdvdman_istruct.m_medium_removal_state;
8772 g_cdvdman_istruct.m_medium_removal_state = (u8)wanted_val;
8773 wdata[0] = wanted_val;
8774 retval = set_prev_command(0x31, wdata, sizeof(wdata), (char *)status, 1, 1);
8775 if ( !retval || *status )
8776 {
8777 g_cdvdman_istruct.m_medium_removal_state = saved_medium_removal_state;
8778 }
8779 CpuResumeIntr(state);
8780 return retval;
8781}
8782#endif
8783
8784#ifdef CDVD_VARIANT_XOSD
8785// cppcheck-suppress funcArgNamesDifferent
8786int sceCdGetMediumRemoval(u32 *param, u32 *status)
8787{
8788 int retval;
8789 char rdata[2];
8790
8791 *param = 0;
8792 if ( !g_cdvdman_minver_50600 )
8793 {
8794 *status = 256;
8795 return 1;
8796 }
8797 *status = SCECdErNO;
8798 retval = set_prev_command(0x32, NULL, 0, rdata, sizeof(rdata), 1);
8799 if ( !retval )
8800 {
8801 return 0;
8802 }
8803 *status = (u8)rdata[0];
8804 *param = (u8)rdata[1];
8805 if ( !rdata[0] )
8806 {
8807 g_cdvdman_istruct.m_medium_removal_state = *param;
8808 }
8809 return retval;
8810}
8811#endif
8812
8813#ifdef CDVD_VARIANT_XOSD
8814// cppcheck-suppress funcArgNamesDifferent
8815int sceCdXDVRPReset(u8 arg1, u32 *status)
8816{
8817 char wdata[1];
8818
8819 if ( !g_cdvdman_minver_50600 )
8820 {
8821 *status = 256;
8822 return 1;
8823 }
8824 *status = SCECdErNO;
8825 wdata[0] = arg1;
8826 return set_prev_command(0x33, wdata, sizeof(wdata), (char *)status, 1, 1);
8827}
8828#endif
8829
8830#ifdef CDVD_VARIANT_XOSD
8831static int sc_ffffffd8(u32 *status)
8832{
8833 int retval;
8834
8835 if ( !g_cdvdman_minver_50600 )
8836 {
8837 *status = 256;
8838 return 1;
8839 }
8840 *status = SCECdErNO;
8841 retval = set_prev_command(0x34, NULL, 0, (char *)status, 1, 1);
8842 if ( !retval )
8843 {
8844 return 0;
8845 }
8846 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
8847 return retval;
8848}
8849#endif
8850
8851#ifdef CDVD_VARIANT_XOSD
8852#ifdef DEAD_CODE
8853int cdvdman_scmd_sender_35(u32 *param, u32 *status)
8854{
8855 int retval;
8856 char rdata[2];
8857
8858 *param = 0;
8859 if ( !g_cdvdman_minver_50600 )
8860 {
8861 *status = 256;
8862 return 1;
8863 }
8864 *status = SCECdErNO;
8865 retval = set_prev_command(0x35, NULL, 0, rdata, sizeof(rdata), 1);
8866 if ( !retval )
8867 {
8868 return 0;
8869 }
8870 *status = (u8)rdata[0];
8871 *param = (u8)rdata[1];
8872 return retval;
8873}
8874#endif
8875#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:7139
int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
Definition cdvdman.c:5453
int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
int sceCdSpinCtrlIOP(u32 speed)
Definition cdvdman.c:2195
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 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 RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition intrman.c:125
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:2580
char name[16]
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:7543
int sceCdReadRegionParams(u32 *arg1, u32 *result)
int sceCdPowerOff(u32 *result)
Definition cdvdman.c:7572
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:4529
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:7291
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition cdvdman.c:2423
int sceCdReadConsoleID(u8 *buffer, u32 *result)
int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
Definition cdvdman.c:2202
int sceCdReadClock(sceCdCLOCK *clock)
Definition cdvdman.c:7946
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:2414
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:5417
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:2078
int sceCdStStart(u32 lbn, sceCdRMode *mode)
Definition cdi.c:202
@ SCECdSpinX1
@ SCECdSpinX2
@ SCECdSpinNm2
@ SCECdSpinMax
@ SCECdSpinStm
@ SCECdSpinNom
@ SCECdSpinMx
@ SCECdSpinX12
@ SCECdSpinX4
void * sceCdPOffCallback(void(*func)(void *userdata), void *userdata)
Definition cdvdman.c:3882
int sceCdBootCertify(const u8 *romname)
int sceCdChgSys(u32 arg1)
int sceCdReadConfig(void *buffer, u32 *result)
int sceCdMV(u8 *buffer, u32 *status)
Definition cdvdman.c:7398
@ 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:8480
int sceCdBuzzerCtl(u32 *result)
int sceCdRI(u8 *buffer, u32 *result)
Definition cdvdman.c:7280
@ 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:6091
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:6865
int sceCdStop(void)
Definition cdi.c:157
int sceCdReadChain(sceCdRChain *tag, sceCdRMode *mode)
Definition cdvdman.c:7050
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:7604
@ SCECdStatSpin
@ SCECdStatPause
@ SCECdStatShellOpen
@ SCECdStatStop
@ SCECdEXIT
@ SCECdINIT
Definition cdvdman.c:43
Definition cdvdman.c:76
#define EA_MULTI
Definition thevent.h:35